Changeset 4307 for icGREP


Ignore:
Timestamp:
Nov 18, 2014, 12:30:43 PM (5 years ago)
Author:
cameron
Message:

Parsing escaped set vs. escaped codepoints

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

Legend:

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

    r4306 r4307  
    66
    77#include <re/re_parser.h>
     8#include <re/re_name.h>
    89#include <re/re_alt.h>
    910#include <re/re_end.h>
     
    1819namespace re {
    1920
    20 RE * RE_Parser::parse(const std::string & regular_expression, const bool allow_escapes_within_charset) {
    21     RE_Parser parser(regular_expression, allow_escapes_within_charset);
     21RE * RE_Parser::parse(const std::string & regular_expression) {
     22    RE_Parser parser(regular_expression);
    2223    RE * re = parser.parse_alt(false);
    2324    if (re == nullptr) {
     
    2728}
    2829
    29 inline RE_Parser::RE_Parser(const std::string & regular_expression, const bool allow_escapes_within_charset)
     30inline RE_Parser::RE_Parser(const std::string & regular_expression)
    3031: _cursor(regular_expression.begin())
    3132, _end(regular_expression.end())
    32 , _allow_escapes_within_charset(allow_escapes_within_charset)
    3333{
    3434
     
    104104                re = parse_any_character();
    105105                break;
     106            case '\\':  // escape processing
     107                ++_cursor;
     108                re = parse_escaped();
     109                break;
    106110            default:
    107111                re = parse_literal();
     
    195199
    196200inline RE * RE_Parser::parse_literal() {
    197     // handle the escaped metacharacter (assuming it is one)
    198     if (*_cursor == '\\') {
    199         return parse_escaped_metacharacter();
    200     }
    201     else {
    202         return makeCC(parse_utf8_codepoint());
    203     }
    204 }
    205 
    206 inline RE * RE_Parser::parse_escaped_metacharacter() {
    207     ++_cursor;
     201    return makeCC(parse_utf8_codepoint());
     202}
     203
     204#define bit40(x) (1ULL << ((x) - 0x40))
     205const uint64_t setEscapeCharacters = bit40('p') | bit40('d') | bit40('w') | bit40('s') | bit40('P') | bit40('D') | bit40('W') | bit40('S');
     206
     207inline bool isSetEscapeChar(char c) {
     208    return c >= 0x40 && c <= 0x7F && ((setEscapeCharacters >> (c - 0x40)) & 1) == 1;
     209}
     210
     211inline RE * RE_Parser::parse_escaped() {
    208212    throw_incomplete_expression_error_if_end_of_stream();
     213    if (isSetEscapeChar(*_cursor))
     214      return parse_escaped_set();
     215    else
     216      return makeCC(parse_escaped_codepoint());
     217}
     218
     219RE * makeDigitSet() {
     220  return makeName("Nd", Name::Type::UnicodeCategory);
     221}
     222
     223RE * makeWhitespaceSet() {
     224  throw ParseFailure("\\s not implemented.");
     225}
     226
     227RE * makeWordSet() {
     228  throw ParseFailure("\\w not implemented.");
     229}
     230
     231RE * makeComplement(RE * s) {
     232  return makeDiff(makeAny(), s);
     233}
     234
     235inline RE * RE_Parser::parse_escaped_set() {
    209236    switch (*_cursor) {
    210237        case 'P':
     
    212239        case 'p':
    213240            return parse_unicode_category();
    214                 default:
    215                         return makeCC(parse_escaped_codepoint());
    216     }
    217     throw ParseFailure("Illegal backslash escape!");
     241        case 'd':
     242            ++_cursor;
     243            return makeDigitSet();
     244        case 'D':
     245            ++_cursor;
     246            return makeComplement(makeDigitSet());
     247        case 's':
     248            ++_cursor;
     249            return makeWhitespaceSet();
     250        case 'S':
     251            ++_cursor;
     252            return makeComplement(makeWhitespaceSet());
     253        case 'w':
     254            ++_cursor;
     255            return makeWordSet();
     256        case 'W':
     257            ++_cursor;
     258            return makeComplement(makeWordSet());
     259        default:
     260            throw ParseFailure("Internal error");
     261    }
    218262}
    219263
     
    464508                        if (((*_cursor >= 'A') && (*_cursor <= 'Z')) || ((*_cursor >= 'a') && (*_cursor <= 'z')))
    465509                                throw ParseFailure("Undefined or unsupported escape sequence");
     510                        else if ((*_cursor < 0x20) || (*_cursor >= 0x7F))
     511                                throw ParseFailure("Illegal escape sequence");
    466512                        else return static_cast<unsigned>(*_cursor++);
    467513        }
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r4306 r4307  
    2222public:
    2323
    24     static RE * parse(const std::string &intput_string, const bool allow_escapes_within_charset = false);
     24    static RE * parse(const std::string &input_string);
    2525
    2626private:
     
    2828    typedef std::string::const_iterator cursor_t;
    2929
    30     RE_Parser(const std::string & regular_expression, const bool allow_escapes_within_charset);
     30    RE_Parser(const std::string & regular_expression);
    3131
    3232    RE * parse_alt(const bool subexpression);
     
    4444    RE * parse_literal();
    4545
    46     RE * parse_escaped_metacharacter();
     46    RE * parse_escaped();
     47
     48    RE * parse_escaped_set();
    4749
    4850    unsigned parse_utf8_codepoint();
     
    6870    cursor_t                    _cursor;
    6971    const cursor_t              _end;
    70     const bool                  _allow_escapes_within_charset;
    7172};
    7273
Note: See TracChangeset for help on using the changeset viewer.