Changeset 4798


Ignore:
Timestamp:
Sep 27, 2015, 1:40:55 AM (2 years ago)
Author:
nmedfort
Message:

Reverted unintended modification of RE parser

Location:
icGREP/icgrep-devel/icgrep/re
Files:
2 edited

Legend:

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

    r4797 r4798  
    3535    RE_Parser parser(regular_expression);
    3636    parser.fModeFlagSet = initialFlags;
     37    parser.fNested = false;
    3738    RE * re = parser.parse_RE();
    3839    if (re == nullptr) {
     
    4647    , _end(regular_expression.end())
    4748    , fModeFlagSet(0)
     49    , fNested(false)
    4850    {
    49        
    50     }
    51    
     51
     52    }
     53
    5254RE * makeLookAheadAssertion(RE * r) {
    5355    return makeAssertion(r, Assertion::Kind::Lookahead, Assertion::Sense::Positive);
     
    7577    return r;
    7678}
    77    
     79
    7880RE * RE_Parser::parse_RE() {
    7981    RE * r = parse_alt();
    80     if (_cursor != _end) {
    81         throw ParseFailure("Unrecognized junk remaining at end of regexp");
    82     }
    8382    return r;
    8483}
     
    128127            case '|': case ')':
    129128                return nullptr;  // This is ugly.
    130             case '*': case '+': case '?': case '{': 
     129            case '*': case '+': case '?': case '{':
    131130                throw NothingToRepeat();
    132             case ']': case '}':
     131            case ']':
    133132                if (LEGACY_UNESCAPED_RBRAK_RBRACE_ALLOWED) {
    134133                    return build_CC(parse_utf8_codepoint());
    135134                }
    136                 else throw ParseFailure("Use  \\] or \\} for literal ] or }.");
     135                else throw ParseFailure("Use  \\] for literal ].");
     136            case '}':
     137                if (fNested) {
     138                    return nullptr;  //  a recursive invocation for a regexp in \N{...}
     139                }
     140                else if (LEGACY_UNESCAPED_RBRAK_RBRACE_ALLOWED) {
     141                    return build_CC(parse_utf8_codepoint());
     142                }
     143                else throw ParseFailure("Use \\} for literal }.");
    137144            case '[':
    138145                _cursor++;
     
    150157    return re;
    151158}
    152    
    153    
     159
     160
    154161// Parse some kind of parenthesized group.  Input precondition: _cursor
    155162// after the (
     
    242249                else {  // if *_cursor == ')'
    243250                    ++_cursor;
    244                     // return immediately without restoring mode flags
     251            // return immediately without restoring mode flags
    245252                    return parse_next_item();
    246253                }
     
    261268    return group_expr;
    262269}
    263    
     270
    264271RE * RE_Parser::extend_item(RE * re) {
    265272    int lower_bound, upper_bound;
     
    358365
    359366#define bit40(x) (1ULL << ((x) - 0x40))
    360 const uint64_t setEscapeCharacters = bit40('b') | bit40('p') | bit40('d') | bit40('w') | bit40('s') | 
    361                                      bit40('B') | bit40('P') | bit40('D') | bit40('W') | bit40('S');
     367const uint64_t setEscapeCharacters = bit40('b') | bit40('p') | bit40('d') | bit40('w') | bit40('s') |
     368                                     bit40('B') | bit40('P') | bit40('D') | bit40('W') | bit40('S') | bit40('N');
    362369
    363370inline bool isSetEscapeChar(char c) {
     
    367374inline RE * RE_Parser::parse_escaped() {
    368375    throw_incomplete_expression_error_if_end_of_stream();
    369     if (isSetEscapeChar(*_cursor)) 
     376    if (isSetEscapeChar(*_cursor))
    370377      return parseEscapedSet();
    371     else 
     378    else
    372379      return build_CC(parse_escaped_codepoint());
    373380}
     
    411418            ++_cursor;
    412419            return complemented ? makeComplement(s) : s;
     420        case 'N':
     421            ++_cursor;
     422            if (_cursor == _end || *_cursor != '{') throw ParseFailure("Malformed \\N expression");
     423            ++_cursor;
     424            s = parseNamePatternExpression();
     425            if (_cursor == _end || *_cursor != '}') throw ParseFailure("Malformed \\N expression");
     426            ++_cursor;
     427            return s;
    413428        default:
    414429            throw ParseFailure("Internal error");
     
    452467        throw InvalidUTF8Encoding();
    453468    }
    454     // It is an error if a 4-byte sequence is used to encode a codepoint 
    455     // above the Unicode maximum.   
     469    // It is an error if a 4-byte sequence is used to encode a codepoint
     470    // above the Unicode maximum.
    456471    if (cp > CC::UNICODE_MAX) {
    457472        throw InvalidUTF8Encoding();
     
    523538}
    524539
     540CC * RE_Parser::parseNamePatternExpression(){
     541
     542    re::ModeFlagSet outerFlags = fModeFlagSet;
     543    fModeFlagSet = 1;
     544
     545    bool outerNested = fNested;
     546    fNested = true;
     547
     548    RE * nameRE = parse_RE();
     549
     550    // Reset outer parsing state.
     551    fModeFlagSet = outerFlags;
     552    fNested = outerNested;
     553
     554
     555    // Embed the nameRE in ";.*$nameRE" to skip the codepoint field of Uname.txt
     556    RE * embedded = makeSeq({re::makeCC(0x3B), re::makeRep(re::makeAny(), 0, Rep::UNBOUNDED_REP), nameRE});
     557
     558
     559    throw ParseFailure("\\N{...} character name expression recognized but not yet supported.");
     560
     561
     562}
     563
     564
    525565CharsetOperatorKind RE_Parser::getCharsetOperator() {
    526566    throw_incomplete_expression_error_if_end_of_stream();
     
    566606            return emptyOperator;
    567607    }
    568 }           
    569    
     608}
     609
    570610// Precondition: cursor is immediately after opening '[' character
    571611RE * RE_Parser::parse_charset() {
    572612    // Sets are accumulated using two variables:
    573613    // subexprs accumulates set expressions such as \p{Lu}, [\w && \p{Greek}]
    574     // cc accumulates the literal and calculated codepoints and ranges 
     614    // cc accumulates the literal and calculated codepoints and ranges
    575615    std::vector<RE *> subexprs;
    576616    CC * cc = makeCC();
     
    580620    enum {NoItem, CodepointItem, RangeItem, SetItem, BrackettedSetItem} lastItemKind = NoItem;
    581621    codepoint_t lastCodepointItem;
    582    
     622
    583623    bool havePendingOperation = false;
    584624    CharsetOperatorKind pendingOperationKind;
    585625    RE * pendingOperand;
    586    
     626
    587627    // If the first character after the [ is a ^ (caret) then the matching character class is complemented.
    588628    bool negated = false;
     
    710750                break;
    711751            case hyphenChar:
    712                 cc->insert('-'); 
     752                cc->insert('-');
    713753                lastItemKind = CodepointItem;
    714754                lastCodepointItem = static_cast<codepoint_t> ('-');
    715755                break;
    716756            case ampChar:
    717                 cc->insert('&'); 
     757                cc->insert('&');
    718758                lastItemKind = CodepointItem;
    719759                lastCodepointItem = static_cast<codepoint_t> ('&');
     
    761801// 4. General octal notation o\{[0-7]+\}
    762802// 5. General hex notation x\{[0-9A-Fa-f]+\}
    763 // 6. An error for any unrecognized alphabetic escape 
     803// 6. An error for any unrecognized alphabetic escape
    764804// 7. An escaped ASCII symbol, standing for itself
    765805
     
    789829            ++_cursor;
    790830            return parse_octal_codepoint(0,3);
    791         case 'o': 
     831        case 'o':
    792832            ++_cursor;
    793833            throw_incomplete_expression_error_if_end_of_stream();
     
    801841                throw ParseFailure("Malformed octal escape sequence");
    802842            }
    803         case 'x': 
     843        case 'x':
    804844            ++_cursor;
    805845            throw_incomplete_expression_error_if_end_of_stream();
     
    825865                return parse_hex_codepoint(4,4);  // ICU compatibility
    826866            }
    827         case 'U': 
     867        case 'U':
    828868            ++_cursor;
    829869            return parse_hex_codepoint(8,8);  // ICU compatibility
    830         case 'N':
    831             ++_cursor;
    832             throw ParseFailure("\\N{...} character name syntax not yet supported.");
    833 
    834870        default:
    835871            // Escaped letters should be reserved for special functions.
     
    868904            value = (value * 16) | (t - '0');
    869905        }
    870         else {   
     906        else {
    871907            value = (value * 16) | ((t | 32) - 'a') + 10;
    872908        }
     
    903939    else cc->insert_range(lo, hi);
    904940}
    905    
     941
    906942RE * RE_Parser::makeComplement(RE * s) {
    907943  return makeDiff(makeAny(), s);
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r4797 r4798  
    2121
    2222enum CharsetOperatorKind
    23         {intersectOp, setDiffOp, ampChar, hyphenChar, rangeHyphen, posixPropertyOpener, setOpener, setCloser, backSlash, emptyOperator};
     23    {intersectOp, setDiffOp, ampChar, hyphenChar, rangeHyphen, posixPropertyOpener, setOpener, setCloser, backSlash, emptyOperator};
    2424
    25 enum ModeFlagType 
     25enum ModeFlagType
    2626    {CASE_INSENSITIVE_MODE_FLAG = 1,
    2727     MULTILINE_MODE_FLAG = 2,      // not currently implemented
     
    2929     IGNORE_SPACE_MODE_FLAG = 8,   // not currently implemented
    3030     UNIX_LINES_MODE_FLAG = 16};   // not currently implemented
    31    
     31
    3232const int MAX_REPETITION_LOWER_BOUND = 1024;
    3333const int MAX_REPETITION_UPPER_BOUND = 2048;
    3434
    3535typedef unsigned ModeFlagSet;
    36    
     36
    3737class RE_Parser
    3838{
     
    5151
    5252    RE_Parser(const std::string & regular_expression);
    53    
     53
    5454    RE_Parser(const std::string & regular_expression, ModeFlagSet initialFlags);
    5555
    5656    RE * parse_RE();
    57    
     57
    5858    RE * parse_alt();
    59    
     59
    6060    RE * parse_seq();
    6161
    6262    RE * parse_next_item();
    63    
     63
    6464    RE * parse_group();
    65    
     65
    6666    RE * extend_item(RE * re);
    6767
     
    6969
    7070    unsigned parse_int();
    71    
     71
    7272    RE * parse_escaped();
    7373
     
    7777
    7878    Name * parsePropertyExpression();
    79        
     79
     80    CC * parseNamePatternExpression();
     81
    8082    RE * makeComplement(RE * s);
    8183    RE * makeWordBoundary();
     
    8991    Name * createName(const std::string prop, const std::string value);
    9092
    91         CharsetOperatorKind getCharsetOperator();
     93    CharsetOperatorKind getCharsetOperator();
    9294
    9395    RE * parse_charset();
     
    102104
    103105    inline void throw_incomplete_expression_error_if_end_of_stream() const;
    104    
     106
    105107    // CC insertion dependent on case-insensitive flag.
    106108    CC * build_CC(codepoint_t cp);
    107    
     109
    108110    void CC_add_codepoint(CC * cc, codepoint_t cp);
    109    
     111
    110112    void CC_add_range(CC * cc, codepoint_t lo, codepoint_t hi);
    111113
     
    117119    const cursor_t              _end;
    118120    ModeFlagSet                 fModeFlagSet;
     121    bool                        fNested;
    119122    NameMap                     mNameMap;
    120123};
Note: See TracChangeset for help on using the changeset viewer.