Changeset 5792


Ignore:
Timestamp:
Dec 20, 2017, 8:00:59 AM (4 weeks ago)
Author:
cameron
Message:

\N{...} expressions now anchored; name expresions in ranges functional

Location:
icGREP/icgrep-devel
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/QA/greptest.xml

    r5752 r5792  
    847847<grepcase regexp="(?:\p{greek}\p{greek}\p{greek})" datafile="upper_lower_greek" grepcount="3"/>
    848848
    849 <grepcase regexp="\N{AIRPLANE}" datafile="../All_good" grepcount="8"/>
    850 
     849<grepcase regexp="\p{name=/AIRPLANE/}" datafile="../All_good" grepcount="8"/>
     850<grepcase regexp="[\N{GREEK CAPITAL LETTER ALPHA}-\N{Greek capital letter UPSILON with DIALYTIKA}]" grepcount="27"/>
    851851</greptest>
  • icGREP/icgrep-devel/icgrep/re/re_parser.cpp

    r5791 r5792  
    260260}
    261261   
    262     RE * RE_Parser::parse_back_reference() {
    263         mCursor++;
    264         std::string backref = std::string(mCursor.pos()-2, mCursor.pos());
    265         auto key = std::make_pair("", backref);
    266         auto f = mNameMap.find(key);
    267         if (f != mNameMap.end()) {
    268             return makeReference(backref, f->second);
    269         }
    270         else {
    271             ParseFailure("Back reference " + backref + " without prior capture group.");
    272         }
    273     }
     262RE * RE_Parser::parse_back_reference() {
     263    mCursor++;
     264    std::string backref = std::string(mCursor.pos()-2, mCursor.pos());
     265    auto key = std::make_pair("", backref);
     266    auto f = mNameMap.find(key);
     267    if (f != mNameMap.end()) {
     268        return makeReference(backref, f->second);
     269    }
     270    else {
     271        ParseFailure("Back reference " + backref + " without prior capture group.");
     272    }
     273}
    274274
    275275#define ENABLE_EXTENDED_QUANTIFIERS true
     
    324324unsigned RE_Parser::parse_int() {
    325325    unsigned value = 0;
    326     if (!isdigit(*mCursor)) ParseFailure("Expecting integer");
    327     while (isdigit(*mCursor)) {
     326    if (!atany("0123456789")) ParseFailure("Expecting integer");
     327    do {
    328328        value *= 10;
    329         value += static_cast<int>(*mCursor++) - 48;
    330     }
     329        value += static_cast<int>(get1()) - 48;
     330    } while (atany("0123456789"));
    331331    return value;
    332332}
     
    353353        else return createCC(cp);
    354354    }
    355     else if (isdigit(*mCursor)) {
     355    else if (atany("123456789")) {
    356356        return parse_back_reference();
    357357    }
     
    535535RE * RE_Parser::parsePropertyExpression() {
    536536    const auto start = mCursor.pos();
    537     while (mCursor.more()) {
    538         bool done = false;
    539         switch (*mCursor) {
    540             case '}': case ':': case '=':
    541                 done = true;
    542         }
    543         if (done) {
    544             break;
    545         }
    546         ++mCursor;
    547     }
    548     if (*mCursor == '=') {
     537    while (mCursor.more() && !atany("}:=")) {
     538        get1();
     539    }
     540    if (accept('=')) {
    549541        // We have a property-name = value expression
    550         const auto prop_end = mCursor.pos();
    551         mCursor++;
     542        const auto prop_end = mCursor.pos()-1;
    552543        auto val_start = mCursor.pos();
    553         if (*val_start == '/') {
     544        if (accept('/')) {
    554545            // property-value is another regex
    555546            auto previous = val_start;
    556             auto current = (++mCursor).pos();
     547            auto current = mCursor.pos();
    557548            val_start = current;
    558549           
     
    616607Name * RE_Parser::parseNamePatternExpression(){
    617608    require('{');
    618     const auto start = mCursor.pos();
    619     while (mCursor.more()) {
    620         if (*mCursor == '\\') {
    621             ++mCursor;
    622             if (!mCursor.more()) {
    623                 break;
    624             }
    625         }
    626         else if (*mCursor == '}') {
    627             break;
    628         }
    629         ++mCursor;
    630     }
    631     std::string nameRegexp = "/(?i)" + std::string(start, mCursor.pos());
     609    std::stringstream nameRegexp;
     610    nameRegexp << "/(?m)^";
     611    while (mCursor.more() && !at('}')) {
     612        if (accept("\\}")) {
     613            nameRegexp << "}";
     614        }
     615        else {
     616            nameRegexp << std::string(1, std::toupper(get1()));
     617        }
     618    }
     619    nameRegexp << "$";
    632620    require('}');
    633     return createName("na", nameRegexp);
     621    return createName("na", nameRegexp.str());
    634622}
    635623
     
    699687
    700688RE * RE_Parser::parse_equivalence_class() {
    701     const auto start = mCursor.pos() - 1;
     689    const auto start = mCursor.pos() - 2;
    702690    while (mCursor.more() && !at('=')) {
    703691        ++mCursor;
    704692    }
     693    require("=]");
    705694    std::string name = std::string(start, mCursor.pos());
    706     require("=]");
    707695    return createName(name);
    708696}
    709697RE * RE_Parser::parse_collation_element() {
    710     const auto start = mCursor.pos() - 1;
     698    const auto start = mCursor.pos() - 2;
    711699    while (mCursor.more() && !at('.')) {
    712700        ++mCursor;
    713701    }
     702    require(".]");
    714703    std::string name = std::string(start, mCursor.pos());
    715     require(".]");
    716704    return createName(name);
    717705}
     
    795783    codepoint_t value = 0;
    796784    int count = 0;
    797     while (mCursor.more() && count < maxdigits) {
    798         const char t = *mCursor;
    799         if (t < '0' || t > '7') {
    800             break;
    801         }
     785    while (mCursor.more() && atany("01234567") && count < maxdigits) {
     786        const char t = get1();
    802787        value = value * 8 | (t - '0');
    803         ++mCursor;
    804788        ++count;
    805789    }
     
    812796    codepoint_t value = 0;
    813797    int count = 0;
    814     while (mCursor.more() && isxdigit(*mCursor) && count < maxdigits) {
    815         const char t = *mCursor;
     798    while (mCursor.more() && atany("0123456789abcdefABCDEF") && count < maxdigits) {
     799        const char t = get1();
    816800        if (isdigit(t)) {
    817801            value = (value * 16) | (t - '0');
     
    820804            value = ((value * 16) | ((t | 32) - 'a')) + 10;
    821805        }
    822         ++mCursor;
    823806        ++count;
    824807    }
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r5790 r5792  
    155155        }
    156156    }
     157   
     158    inline char get1() { return *mCursor++;}
     159
    157160   
    158161    RE_Parser(const std::string & regular_expression);
  • icGREP/icgrep-devel/icgrep/re/re_range.cpp

    r5788 r5792  
    1717RE * makeRange(RE * lo, RE * hi) {
    1818    if (isa<CC>(lo) && isa<CC>(hi)) {
    19         if (!(dyn_cast<CC>(lo)->count() == 1) && (dyn_cast<CC>(hi)->count() == 1))
    20             llvm::report_fatal_error("illegal range operand");
     19        if (!((dyn_cast<CC>(lo)->count() == 1) && (dyn_cast<CC>(hi)->count() == 1)))
     20            llvm::report_fatal_error("invalid range operand");
    2121        auto lo_val = dyn_cast<CC>(lo)->front().first;
    2222        auto hi_val = dyn_cast<CC>(hi)->front().first;
  • icGREP/icgrep-devel/icgrep/re/re_toolchain.cpp

    r5786 r5792  
    177177    Var * const basis = kernel->getInputStreamVar("basis");
    178178    cc::CC_Compiler cc_compiler(kernel, basis);
     179    // compile Unicode names
    179180    RE_Compiler re_compiler(kernel, cc_compiler);
    180181    return re_compiler.compile(re_ast);
Note: See TracChangeset for help on using the changeset viewer.