Ignore:
Timestamp:
Sep 27, 2014, 11:12:13 PM (5 years ago)
Author:
nmedfort
Message:

Modified RE module to use a LLVM-like dyn_cast system; added 'make' functions to hide RE constructors.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/re/re_parser.cpp

    r4193 r4194  
    1414#include <algorithm>
    1515
     16namespace re {
     17
    1618RE * RE_Parser::parse_re(const std::string & regular_expression, const bool allow_escapes_within_charset) {
    1719    RE_Parser parser(regular_expression, allow_escapes_within_charset);
     
    4547
    4648RE * RE_Parser::parse_alt(const bool subexpression) {
    47     std::unique_ptr<Alt> alt(new Alt());
     49    std::unique_ptr<Alt> alt(makeAlt());
    4850    for (;;) {
    4951        alt->push_back(parse_seq());
     
    7072
    7173inline RE * RE_Parser::parse_seq() {
    72     std::unique_ptr<Seq> seq(new Seq());
     74    std::unique_ptr<Seq> seq(makeSeq());
    7375    for (;;) {
    7476        RE * re = parse_next_token();
     
    9597            case '^':
    9698                ++_cursor;
    97                 re = new Start;
     99                re = makeStart();
    98100                break;
    99101            case '$':
    100102                ++_cursor;
    101                 re = new End;
     103                re = makeEnd();
    102104                break;
    103105            case '|': case ')':
     
    120122
    121123CC * RE_Parser::parse_any_character() {
    122     CC * cc = new CC();
     124    CC * cc = makeCC();
    123125    cc->insert_range(0, 9);
    124     cc->insert_range(11, 0x10FFFF);
     126    cc->insert_range(11, CC::UNICODE_MAX);
    125127    ++_cursor;
    126128    return cc;
     
    134136        case '*':
    135137            ++_cursor; // skip past the '*'
    136             re = new Rep(re, 0, Rep::UNBOUNDED_REP);
     138            re = makeRep(re, 0, Rep::UNBOUNDED_REP);
    137139            break;
    138140        case '?':
    139141            ++_cursor; // skip past the '?'
    140             re = new Rep(re, 0, 1);
     142            re = makeRep(re, 0, 1);
    141143            break;
    142144        case '+':
    143145            ++_cursor; // skip past the '+'
    144             re = new Rep(re, 1, Rep::UNBOUNDED_REP);
     146            re = makeRep(re, 1, Rep::UNBOUNDED_REP);
    145147            break;
    146148        case '{':
     
    168170    throw_incomplete_expression_error_if_end_of_stream();
    169171    if (*_cursor == '}') {
    170         rep = new Rep(re, lower_bound, lower_bound);
     172        rep = makeRep(re, lower_bound, lower_bound);
    171173    }
    172174    else if (*_cursor != ',') {
     
    177179        throw_incomplete_expression_error_if_end_of_stream();
    178180        if (*_cursor == '}') {
    179             rep = new Rep(re, lower_bound, Rep::UNBOUNDED_REP);
     181            rep = makeRep(re, lower_bound, Rep::UNBOUNDED_REP);
    180182        }
    181183        else {
     
    184186                throw BadUpperBound();
    185187            }
    186             rep = new Rep(re, lower_bound, upper_bound);
     188            rep = makeRep(re, lower_bound, upper_bound);
    187189        }
    188190    }
     
    197199    }
    198200    else {
    199         return new CC(parse_utf8_codepoint());
     201        return makeCC(parse_utf8_codepoint());
    200202    }
    201203}
     
    209211        case '.': case '?': case '[': case '\\':
    210212        case ']': case '{': case '|': case '}':
    211             return new CC(*_cursor++);
     213            return makeCC(*_cursor++);
    212214        case 'u':
    213             return new CC(parse_hex());
     215            return makeCC(parse_hex());
    214216        case 'P':
    215217            negated = true;
     
    245247                }
    246248                c = (c << 6) | static_cast<unsigned>(*_cursor & 0x3F);
    247                 // It is an error if a 3-byte sequence is used to encode a codepoint < 0x800
    248                 // or a 4-byte sequence is used to encode a codepoint < 0x10000.
    249                 // if (((bytes == 1) && (c < 0x20)) || ((bytes == 2) && (c < 0x10))) {
    250                 if ((c << (bytes - 1)) < 0x20) {
     249                // It is an error if a 3-byte sequence is used to encode a codepoint < 0x800
     250                // or a 4-byte sequence is used to encode a codepoint < 0x10000.
     251                // if (((bytes == 1) && (c < 0x20)) || ((bytes == 2) && (c < 0x10))) {
     252                if ((c << (bytes - 1)) < 0x20) {
    251253                    throw InvalidUTF8Encoding();
    252254                }
    253                  
    254255            }
    255256        }
     
    257258    // It is an error if a 4-byte sequence is used to encode a codepoint
    258259    // above the Unicode maximum.   
    259     if (c > 0x10FFFF) throw InvalidUTF8Encoding();
     260    if (c > CC::UNICODE_MAX) {
     261        throw InvalidUTF8Encoding();
     262    }
    260263    return c;
    261264}
     
    263266inline Name * RE_Parser::parse_unicode_category(const bool negated) {
    264267    if (++_cursor != _end && *_cursor == '{') {
    265         std::unique_ptr<Name> name = std::unique_ptr<Name>(new Name);
    266         name->setType(Name::UnicodeCategory);
    267         name->setNegated(negated);
    268268        const cursor_t start = _cursor + 1;
    269269        for (;;) {
     270            if (++_cursor == _end) {
     271                throw UnclosedUnicodeCharacterClass();
     272            }
     273            if (*_cursor == '}') {
     274                break;
     275            }
    270276            ++_cursor;
    271             if (_cursor == _end) {
    272                 throw UnclosedUnicodeCharacterClass();
    273             }
    274             if (*_cursor == '}') {
    275                 break;
    276             }
    277             ++_cursor;
    278         }
    279         name->setName(std::string(start, _cursor));
    280         ++_cursor;
    281         return name.release();
     277        }
     278        return makeName(std::string(start, _cursor++), negated, Name::Type::UnicodeCategory);
    282279    }
    283280    throw ParseFailure("Incorrect Unicode character class format!");
     
    285282
    286283RE * RE_Parser::parse_charset() {
    287     std::unique_ptr<CC> cc(new CC());
     284    std::unique_ptr<CC> cc(makeCC());
    288285    bool negated = false;
    289     bool included_closing_square_bracket = false;
    290286    cursor_t start = ++_cursor;
    291287    while (_cursor != _end) {
     
    306302                    cc->insert(']');
    307303                    ++_cursor;
    308                     included_closing_square_bracket = true;
    309304                    literal = false;
    310305                    break;
     
    322317                    const cursor_t next = _cursor + 1;
    323318                    if (next == _end) {
    324                         goto parse_failed;
     319                        throw UnclosedCharacterClass();
    325320                    }
    326321                    if ((start == _cursor) ? (*next != '-') : (*next == ']')) {
     
    357352        }
    358353    }
    359 parse_failed:
    360     if (included_closing_square_bracket) {
    361         throw ParseFailure("One ']' cannot close \"[]\" or \"[^]\"; use \"[]]\" or \"[^]]\" instead.");
    362     }
    363     else {
    364         throw UnclosedCharacterClass();
    365     }
     354    throw UnclosedCharacterClass();
    366355}
    367356
     
    441430    if (_cursor == _end) throw IncompleteRegularExpression();
    442431}
     432
     433}
Note: See TracChangeset for help on using the changeset viewer.