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

Last change on this file since 5787 was 5787, checked in by cameron, 11 months ago

RE parser restructuring; parsing symbolic ranges, collation and equivalence exprs

File size: 6.2 KB
Line 
1/*
2 *  Copyright (c) 2014-6 International Characters.
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
10#include <map>                           // for map
11#include <re/re_memoizer.hpp>            // for Memoizer
12#include "re/re_cc.h"                    // for codepoint_t, CC (ptr only)
13namespace re { class Name; }
14
15namespace re {
16
17enum RE_Syntax {FixedStrings, BRE, ERE, PCRE, PROSITE};
18
19enum CharsetOperatorKind
20    {intersectOp, setDiffOp, ampChar, hyphenChar, rangeHyphen, posixPropertyOpener, setOpener, setCloser, backSlash, emptyOperator};   
21   
22enum ModeFlagType : unsigned {
23    DEFAULT_MODE = 0,
24    CASE_INSENSITIVE_MODE_FLAG = 1,
25    MULTILINE_MODE_FLAG = 2,
26    DOTALL_MODE_FLAG = 4,         // not currently implemented
27    IGNORE_SPACE_MODE_FLAG = 8,
28    UNIX_LINES_MODE_FLAG = 16,
29    GRAPHEME_CLUSTER_MODE = 32
30};
31
32using ModeFlagSet = unsigned;
33
34class RE_Parser {
35public:
36
37    static LLVM_ATTRIBUTE_NORETURN void ParseFailure(std::string errmsg);
38
39    static RE * parse(const std::string &input_string, ModeFlagSet initialFlags, RE_Syntax syntax = RE_Syntax::PCRE, bool ByteMode = false);
40
41protected:
42
43    using NameMap = std::map<std::pair<std::string, std::string>, re::Name *>;
44
45    using cursor_t = std::string::const_iterator;
46
47    using char_t = const std::string::value_type;
48
49    struct Cursor {
50
51        inline Cursor & operator++() {
52            if (LLVM_UNLIKELY(mCursor == mEnd)) {
53                ParseFailure("Incomplete regular expression!");
54            }
55            ++mCursor;
56            return *this;
57        }
58
59        inline Cursor operator++(int) {
60            if (LLVM_UNLIKELY(mCursor == mEnd)) {
61                ParseFailure("Incomplete regular expression!");
62            }
63            Cursor tmp(*this);
64            ++mCursor;
65            return tmp;
66        }
67
68        inline const char_t operator*() const {
69            if (LLVM_UNLIKELY(mCursor == mEnd)) {
70                return 0;
71            }
72            return *mCursor;
73        }
74
75        inline bool noMore() const {
76            return mCursor == mEnd;
77        }
78
79        inline bool more() const {
80            return mCursor != mEnd;
81        }
82
83        inline cursor_t::difference_type remaining() const {
84            return mEnd - mCursor;
85        }
86
87        inline cursor_t pos() const {
88            return mCursor;
89        }
90       
91       
92        Cursor(const std::string & expression) : mCursor(expression.cbegin()), mEnd(expression.cend()) {}
93        Cursor(const Cursor & cursor) : mCursor(cursor.mCursor), mEnd(cursor.mEnd) {}
94        inline Cursor & operator=(const Cursor & cursor) {
95            mCursor = cursor.mCursor;
96            mEnd = cursor.mEnd;
97            return *this;
98        }
99    private:
100        cursor_t    mCursor;
101        cursor_t    mEnd;
102    };
103
104   
105   
106    inline bool at(char c) {
107        return (mCursor.more()) && (*mCursor == c);
108    }
109   
110    inline bool accept(char c) {
111        if (at(c)) {
112            mCursor++;
113            return true;
114        }
115        return false;
116    }
117   
118    inline bool atany(std::string s) {
119        if (mCursor.noMore()) return false;
120        for (unsigned i = 0; i < s.length(); i++) {
121            if (s[i] == *mCursor) return true;
122        }
123        return false;
124    }
125   
126    inline bool at(std::string s) {
127        Cursor tmp = mCursor;
128        for (unsigned i = 0; i < s.length(); i++) {
129            if (tmp.noMore() || (s[i] != *tmp)) return false;
130            tmp++;
131        }
132        return true;
133    }
134   
135    inline bool accept(std::string s) {
136        for (unsigned i = 0; i < s.length(); i++) {
137            if (mCursor.noMore() || (s[i] != *mCursor)) return false;
138            mCursor++;
139        }
140        return true;
141    }
142   
143
144    RE_Parser(const std::string & regular_expression);
145
146    RE_Parser(const std::string & regular_expression, ModeFlagSet initialFlags);
147
148    virtual RE * parse_RE();
149
150    virtual RE * parse_alt();
151   
152    virtual RE * parse_seq();
153
154    virtual RE * parse_next_item();
155
156    virtual RE * parse_group();
157
158    virtual bool isSetEscapeChar(char c);
159
160    virtual RE * extend_item(RE * re);
161
162    RE * parseGraphemeBoundary(RE * re);
163
164    virtual std::pair<int, int> parse_range_bound();
165
166    unsigned parse_int();
167
168    virtual RE * parse_escaped();
169
170    virtual RE * parseEscapedSet();
171
172    codepoint_t parse_literal_codepoint();
173   
174    codepoint_t parse_utf8_codepoint();
175
176    virtual RE * parsePropertyExpression();
177
178    Name * parseNamePatternExpression();
179
180    RE * makeComplement(RE * s);
181    RE * makeWordBoundary();
182    RE * makeWordNonBoundary();
183    RE * makeReBoundary(RE * wordC);
184    RE * makeReNonBoundary(RE * wordC);
185    RE * makeWordBegin();
186    RE * makeWordEnd();
187    Name * makeDigitSet();
188    Name * makeAlphaNumeric();
189    Name * makeWhitespaceSet();
190    Name * makeWordSet();
191   
192    Name * createName(std::string value);
193    Name * createName(std::string prop, std::string value);
194
195    RE * parse_extended_bracket_expression();
196    RE * parse_bracketed_items();
197    RE * range_extend(RE * e1);
198   
199    RE * parse_equivalence_class();
200    RE * parse_collation_element();
201    RE * parse_Posix_class();
202    RE * parse_escaped_char_item();
203   
204    codepoint_t parse_codepoint();
205
206    virtual codepoint_t parse_escaped_codepoint();
207
208    codepoint_t parse_hex_codepoint(int mindigits, int maxdigits);
209
210    codepoint_t parse_octal_codepoint(int mindigits, int maxdigits);
211
212    // CC insertion dependent on case-insensitive flag.
213    Name * createCC(const codepoint_t cp);
214    void insert(CC * cc, const codepoint_t cp);
215    void insert_range(CC * cc, const codepoint_t lo, const codepoint_t hi);
216
217    static std::string canonicalize(const cursor_t begin, const cursor_t end);
218    bool isCharAhead(char c);
219
220protected:
221    bool                        fByteMode;
222    ModeFlagSet                 fModeFlagSet;
223    bool                        fNested;
224    unsigned                    mGroupsOpen;
225    bool                        fSupportNonCaptureGroup;
226    Cursor                      mCursor;
227    unsigned                    mCaptureGroupCount;
228    NameMap                     mNameMap;
229    Memoizer                    mMemoizer;
230    RE_Syntax                   mReSyntax;
231};
232
233}
234
235#endif // RE_PARSER_H
Note: See TracBrowser for help on using the repository browser.