source: icGREP/icgrep-devel/icgrep/re/re_parser_bre.cpp

Last change on this file was 5789, checked in by cameron, 2 months ago

Further parser bug fixes and restructuring

File size: 2.8 KB
Line 
1/*
2 *  Copyright (c) 2016 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#include <re/re_parser_bre.h>
8#include <re/re_alt.h>
9#include <re/re_any.h>
10#include <re/re_seq.h>
11#include <re/re_start.h>
12#include <re/re_end.h>
13#include <re/re_assertion.h>
14#include <re/re_rep.h>
15#include <llvm/Support/raw_ostream.h>
16
17
18namespace re {
19
20
21RE * RE_Parser_BRE::parse_alt() {
22    std::vector<RE *> alt;
23    do {
24        alt.push_back(parse_seq());
25    }
26    while (accept("\\|"));
27    return makeAlt(alt.begin(), alt.end());
28}
29
30RE * RE_Parser_BRE::parse_seq() {
31    std::vector<RE *> seq;
32    if (!mCursor.more() || at("\\|") || at("\\)")) return makeSeq();
33    for (;;) {
34        RE * re = parse_next_item();
35        if (re == nullptr) {
36            break;
37        }
38        re = extend_item(re);
39        seq.push_back(re);
40    }
41    return makeSeq(seq.begin(), seq.end());
42}
43
44
45RE * RE_Parser_BRE::parse_next_item() {
46    if (mCursor.noMore() || at('*') || at("\\?") || at("\\{") || at("\\|")) return nullptr;
47    else if ((mGroupsOpen > 0) && at("\\)")) return nullptr;
48    else if (accept('^')) return makeStart();
49    else if (accept('$')) return makeEnd();
50    else if (accept('.')) return makeAny();
51    else if (accept("\\(")) return parse_group();
52    else if (accept('[')) return parse_bracket_expr();
53    else if (accept('\\')) return parse_escaped();
54    else return createCC(parse_literal_codepoint());
55}
56
57// A parenthesized capture group.  Input precondition: the opening \( has been consumed
58RE * RE_Parser_BRE::parse_group() {
59    mGroupsOpen++;
60    RE * captured = parse_capture_body();
61    require("\\)");
62    mGroupsOpen--;
63    return captured;
64}
65
66// Extend a RE item with one or more quantifiers
67RE * RE_Parser_BRE::extend_item(RE * re) {
68    int lb, ub;
69    if (accept('*')) {lb = 0; ub = Rep::UNBOUNDED_REP;}
70    else if (accept("\\?")) {lb = 0; ub = 1;}
71    else if (accept("\\+")) {lb = 1; ub = Rep::UNBOUNDED_REP;}
72    else if (accept("\\{")) std::tie(lb, ub) = parse_range_bound();
73    else {
74        // No quantifier found.
75        return re;
76    }
77    re = makeRep(re, lb, ub);
78    // The quantified expression may be extended with a further quantifier, e,g., [a-z]\{6,7\}\{2,3\}
79    return extend_item(re);
80}
81
82std::pair<int, int> RE_Parser_BRE::parse_range_bound() {
83    int lb, ub;
84    if (accept(',')) {
85        lb = 0;
86        ub = parse_int();
87    } else {
88        lb = parse_int();
89        if (accept("\\}")) return std::make_pair(lb, lb);
90        else require(',');
91        if (accept("\\}")) return std::make_pair(lb, Rep::UNBOUNDED_REP);
92        ub = parse_int();
93        if (ub < lb) ParseFailure("Upper bound less than lower bound");
94    }
95    require("\\}");
96    return std::make_pair(lb, ub);
97}
98
99}
100
Note: See TracBrowser for help on using the repository browser.