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

Last change on this file since 5161 was 5161, checked in by cameron, 3 years ago

Override LLVM error_handler for return code 2; convert ParseFailure? to LLVM fatal error.

File size: 4.8 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 <re/re_re.h>
11#include <re/re_any.h>
12#include <re/re_name.h>
13#include <UCD/resolve_properties.h>
14#include <string>
15#include <list>
16#include <memory>
17#include <map>
18#include <re/re_memoizer.hpp>
19#include <llvm/Support/ErrorHandling.h>
20
21namespace re {
22
23enum CharsetOperatorKind
24    {intersectOp, setDiffOp, ampChar, hyphenChar, rangeHyphen, posixPropertyOpener, setOpener, setCloser, backSlash, emptyOperator};
25
26enum ModeFlagType : unsigned {
27    NONE = 0,
28    CASE_INSENSITIVE_MODE_FLAG = 1,
29    MULTILINE_MODE_FLAG = 2,      // not currently implemented
30    DOTALL_MODE_FLAG = 4,         // not currently implemented
31    IGNORE_SPACE_MODE_FLAG = 8,   // not currently implemented
32    UNIX_LINES_MODE_FLAG = 16,    // not currently implemented
33    GRAPHEME_CLUSTER_MODE = 32
34};
35
36const int MAX_REPETITION_LOWER_BOUND = 1024;
37const int MAX_REPETITION_UPPER_BOUND = 2048;
38
39typedef unsigned ModeFlagSet;
40
41
42class RE_Parser
43{
44public:
45
46    static RE * parse(const std::string &input_string, ModeFlagSet initialFlags);
47
48   
49    static LLVM_ATTRIBUTE_NORETURN void ParseFailure(std::string errmsg) {
50        llvm::report_fatal_error(errmsg);
51    }
52   
53private:
54    using NameMap = std::map<std::pair<std::string, std::string>, re::Name *>;
55
56    using cursor_t = std::string::const_iterator;
57
58    using char_t = const std::string::value_type;
59
60    struct Cursor {
61
62        inline Cursor & operator++() {
63            if (LLVM_UNLIKELY(mCursor == mEnd)) {
64                ParseFailure("Incomplete regular expression!");
65            }
66            ++mCursor;
67            return *this;
68        }
69
70        inline Cursor operator++(int) {
71            if (LLVM_UNLIKELY(mCursor == mEnd)) {
72                ParseFailure("Incomplete regular expression!");
73            }
74            Cursor tmp(*this);
75            ++mCursor;
76            return tmp;
77        }
78
79        inline const char_t operator*() const {
80            if (LLVM_UNLIKELY(mCursor == mEnd)) {
81                return 0;
82            }
83            return *mCursor;
84        }
85
86        inline bool noMore() const {
87            return mCursor == mEnd;
88        }
89
90        inline bool more() const {
91            return mCursor != mEnd;
92        }
93
94        inline cursor_t::difference_type remaining() const {
95            return mEnd - mCursor;
96        }
97
98        inline cursor_t pos() const {
99            return mCursor;
100        }
101
102        Cursor(const std::string & expression) : mCursor(expression.cbegin()), mEnd(expression.cend()) {}
103        Cursor(const Cursor & cursor) : mCursor(cursor.mCursor), mEnd(cursor.mEnd) {}
104        inline Cursor & operator=(const Cursor & cursor) {
105            mCursor = cursor.mCursor;
106            mEnd = cursor.mEnd;
107            return *this;
108        }
109    private:
110        cursor_t    mCursor;
111        cursor_t    mEnd;
112    };
113
114    RE_Parser(const std::string & regular_expression);
115
116    RE_Parser(const std::string & regular_expression, ModeFlagSet initialFlags);
117
118    RE * parse_RE();
119
120    RE * parse_alt();
121
122    RE * parse_seq();
123
124    RE * parse_next_item();
125
126    RE * parse_group();
127
128    RE * extend_item(RE * re);
129
130    RE * parseGraphemeBoundary(RE * re);
131
132    std::pair<int, int> parse_range_bound();
133
134    unsigned parse_int();
135
136    RE * parse_escaped();
137
138    RE * parseEscapedSet();
139
140    codepoint_t parse_utf8_codepoint();
141
142    RE * parsePropertyExpression();
143
144    Name * parseNamePatternExpression();
145
146    RE * makeComplement(RE * s);
147    RE * makeWordBoundary();
148    RE * makeWordNonBoundary();
149    RE * makeWordBegin();
150    RE * makeWordEnd();
151    Name * makeDigitSet();
152    Name * makeAlphaNumeric();
153    Name * makeWhitespaceSet();
154    Name * makeWordSet();
155   
156    Name * createName(std::string && value);
157    Name * createName(std::string && prop, std::string && value);
158
159    CharsetOperatorKind getCharsetOperator();
160
161    RE * parse_charset();
162
163    codepoint_t parse_codepoint();
164
165    codepoint_t parse_escaped_codepoint();
166
167    codepoint_t parse_hex_codepoint(int mindigits, int maxdigits);
168
169    codepoint_t parse_octal_codepoint(int mindigits, int maxdigits);
170
171    // CC insertion dependent on case-insensitive flag.
172    Name * createCC(const codepoint_t cp);
173    void insert(CC * cc, const codepoint_t cp);
174    void insert_range(CC * cc, const codepoint_t lo, const codepoint_t hi);
175
176    static std::string canonicalize(const cursor_t begin, const cursor_t end);
177
178private:
179
180    ModeFlagSet                 fModeFlagSet;
181    bool                        fNested;
182    bool                        fGraphemeBoundaryPending;
183    Cursor                      mCursor;
184    unsigned                    mCaptureGroupCount;
185    NameMap                     mNameMap;
186    Memoizer                    mMemoizer;
187};
188
189}
190
191#endif // RE_PARSER_H
Note: See TracBrowser for help on using the repository browser.