source: icGREP/icgrep-devel/icgrep/re/re_parser.h @ 5792

Last change on this file since 5792 was 5792, checked in by cameron, 16 months ago

\N{...} expressions now anchored; name expresions in ranges functional

File size: 6.8 KB
RevLine 
[3850]1/*
[5161]2 *  Copyright (c) 2014-6 International Characters.
[3850]3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#ifndef RE_PARSER_H
8#define RE_PARSER_H
9
[5789]10#include <map>
11#include <re/re_memoizer.hpp>
12#include "re/re_cc.h"
13
[5267]14namespace re { class Name; }
[3850]15
[4194]16namespace re {
[4673]17
[5218]18enum RE_Syntax {FixedStrings, BRE, ERE, PCRE, PROSITE};
[5267]19
[4831]20enum ModeFlagType : unsigned {
[5679]21    DEFAULT_MODE = 0,
[4831]22    CASE_INSENSITIVE_MODE_FLAG = 1,
[5787]23    MULTILINE_MODE_FLAG = 2,
[4831]24    DOTALL_MODE_FLAG = 4,         // not currently implemented
[5558]25    IGNORE_SPACE_MODE_FLAG = 8,
26    UNIX_LINES_MODE_FLAG = 16,
[4831]27    GRAPHEME_CLUSTER_MODE = 32
28};
[4798]29
[5267]30using ModeFlagSet = unsigned;
[4798]31
[5267]32class RE_Parser {
[4182]33public:
[3850]34
[5267]35    static LLVM_ATTRIBUTE_NORETURN void ParseFailure(std::string errmsg);
36
[5732]37    static RE * parse(const std::string &input_string, ModeFlagSet initialFlags, RE_Syntax syntax = RE_Syntax::PCRE, bool ByteMode = false);
[3850]38
[5180]39protected:
[5267]40
[4829]41    using NameMap = std::map<std::pair<std::string, std::string>, re::Name *>;
[4671]42
[4819]43    using cursor_t = std::string::const_iterator;
[3850]44
[4829]45    using char_t = const std::string::value_type;
46
47    struct Cursor {
48
49        inline Cursor & operator++() {
50            if (LLVM_UNLIKELY(mCursor == mEnd)) {
[5161]51                ParseFailure("Incomplete regular expression!");
[4829]52            }
53            ++mCursor;
54            return *this;
55        }
56
57        inline Cursor operator++(int) {
58            if (LLVM_UNLIKELY(mCursor == mEnd)) {
[5161]59                ParseFailure("Incomplete regular expression!");
[4829]60            }
61            Cursor tmp(*this);
62            ++mCursor;
63            return tmp;
64        }
65
66        inline const char_t operator*() const {
67            if (LLVM_UNLIKELY(mCursor == mEnd)) {
[4831]68                return 0;
[4829]69            }
70            return *mCursor;
71        }
72
73        inline bool noMore() const {
74            return mCursor == mEnd;
75        }
76
77        inline bool more() const {
78            return mCursor != mEnd;
79        }
80
81        inline cursor_t::difference_type remaining() const {
82            return mEnd - mCursor;
83        }
84
85        inline cursor_t pos() const {
86            return mCursor;
87        }
[5787]88       
89       
[4829]90        Cursor(const std::string & expression) : mCursor(expression.cbegin()), mEnd(expression.cend()) {}
91        Cursor(const Cursor & cursor) : mCursor(cursor.mCursor), mEnd(cursor.mEnd) {}
92        inline Cursor & operator=(const Cursor & cursor) {
93            mCursor = cursor.mCursor;
94            mEnd = cursor.mEnd;
95            return *this;
96        }
97    private:
98        cursor_t    mCursor;
99        cursor_t    mEnd;
100    };
101
[5787]102   
103   
104    inline bool at(char c) {
105        return (mCursor.more()) && (*mCursor == c);
106    }
107   
108    inline bool accept(char c) {
109        if (at(c)) {
110            mCursor++;
111            return true;
112        }
113        return false;
114    }
115   
[5789]116    inline void require(char c) {
117        if (!accept(c)) {
118            if (mCursor.noMore()) ParseFailure("Expecting " + std::string(1, c) + " but end of input encountered");
119            ParseFailure("Expecting " + std::string(1, c) + " but " + std::string(1, *mCursor) + " encountered");
120        }
121    }
122   
[5787]123    inline bool atany(std::string s) {
124        if (mCursor.noMore()) return false;
125        for (unsigned i = 0; i < s.length(); i++) {
126            if (s[i] == *mCursor) return true;
127        }
128        return false;
129    }
130   
131    inline bool at(std::string s) {
132        Cursor tmp = mCursor;
133        for (unsigned i = 0; i < s.length(); i++) {
134            if (tmp.noMore() || (s[i] != *tmp)) return false;
135            tmp++;
136        }
137        return true;
138    }
139   
140    inline bool accept(std::string s) {
[5789]141        Cursor tmp = mCursor;
[5787]142        for (unsigned i = 0; i < s.length(); i++) {
[5789]143            if (tmp.noMore() || (s[i] != *tmp)) return false;
144            tmp++;
[5787]145        }
[5789]146        mCursor = tmp;
[5787]147        return true;
148    }
149   
[5789]150    inline void require(std::string s) {
151        if (!accept(s)) {
152            if (mCursor.noMore()) ParseFailure("Expecting " + s + " but end of input encountered");
[5790]153            size_t rem = mCursor.remaining();
[5789]154            ParseFailure("Expecting " + s + " but " + std::string(mCursor.pos(), mCursor.pos() + std::min(rem, s.length())) + " encountered");
155        }
156    }
157   
[5792]158    inline char get1() { return *mCursor++;}
159
160   
[4307]161    RE_Parser(const std::string & regular_expression);
[4798]162
[4412]163    RE_Parser(const std::string & regular_expression, ModeFlagSet initialFlags);
[3914]164
[5180]165    virtual RE * parse_RE();
[4798]166
[5218]167    virtual RE * parse_alt();
[5754]168   
[5218]169    virtual RE * parse_seq();
[3935]170
[5180]171    virtual RE * parse_next_item();
[4798]172
[5180]173    virtual RE * parse_group();
[5789]174   
175    RE * parse_mode_group(bool & closing_paren_parsed);
[4798]176
[5789]177    RE * parse_capture_body();
178   
179    RE * parse_back_reference();
180   
[5180]181    virtual bool isSetEscapeChar(char c);
[4182]182
[5180]183    virtual RE * extend_item(RE * re);
184
[4829]185    RE * parseGraphemeBoundary(RE * re);
[4182]186
[5180]187    virtual std::pair<int, int> parse_range_bound();
[4829]188
[4311]189    unsigned parse_int();
[4798]190
[5180]191    virtual RE * parse_escaped();
[4182]192
[5180]193    virtual RE * parseEscapedSet();
[4307]194
[5554]195    codepoint_t parse_literal_codepoint();
196   
[4311]197    codepoint_t parse_utf8_codepoint();
[4182]198
[5180]199    virtual RE * parsePropertyExpression();
[4798]200
[4852]201    Name * parseNamePatternExpression();
[4798]202
[4671]203    RE * makeComplement(RE * s);
[4673]204    RE * makeWordBoundary();
205    RE * makeWordNonBoundary();
[5206]206    RE * makeReBoundary(RE * wordC);
207    RE * makeReNonBoundary(RE * wordC);
[5132]208    RE * makeWordBegin();
209    RE * makeWordEnd();
[4829]210    Name * makeDigitSet();
211    Name * makeAlphaNumeric();
212    Name * makeWhitespaceSet();
213    Name * makeWordSet();
[5091]214   
[5241]215    Name * createName(std::string value);
216    Name * createName(std::string prop, std::string value);
[4671]217
[5787]218    RE * parse_extended_bracket_expression();
219    RE * parse_bracketed_items();
220    RE * range_extend(RE * e1);
221   
222    RE * parse_equivalence_class();
223    RE * parse_collation_element();
224    RE * parse_Posix_class();
225    RE * parse_escaped_char_item();
226   
[4311]227    codepoint_t parse_codepoint();
[4182]228
[5180]229    virtual codepoint_t parse_escaped_codepoint();
[4182]230
[4311]231    codepoint_t parse_hex_codepoint(int mindigits, int maxdigits);
[4305]232
[4311]233    codepoint_t parse_octal_codepoint(int mindigits, int maxdigits);
[4305]234
[4316]235    // CC insertion dependent on case-insensitive flag.
[4819]236    Name * createCC(const codepoint_t cp);
237    void insert(CC * cc, const codepoint_t cp);
238    void insert_range(CC * cc, const codepoint_t lo, const codepoint_t hi);
[4798]239
[4671]240    static std::string canonicalize(const cursor_t begin, const cursor_t end);
[5206]241    bool isCharAhead(char c);
[4671]242
[5180]243protected:
[5554]244    bool                        fByteMode;
[4671]245    ModeFlagSet                 fModeFlagSet;
[4798]246    bool                        fNested;
[5752]247    unsigned                    mGroupsOpen;
[5080]248    Cursor                      mCursor;
249    unsigned                    mCaptureGroupCount;
[4671]250    NameMap                     mNameMap;
[4819]251    Memoizer                    mMemoizer;
[5206]252    RE_Syntax                   mReSyntax;
[3850]253};
254
[4194]255}
256
[3850]257#endif // RE_PARSER_H
Note: See TracBrowser for help on using the repository browser.