Changeset 5091 for icGREP/icgrep-devel


Ignore:
Timestamp:
Jul 16, 2016, 12:42:28 PM (3 years ago)
Author:
xuedongx
Message:

delete GCB as a separate type.

Location:
icGREP/icgrep-devel/icgrep
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/UCD/resolve_properties.cpp

    r5037 r5091  
    99#include <re/re_name.h>
    1010#include <re/re_diff.h>
     11#include <re/re_any.h>
     12#include <re/re_start.h>
     13#include <re/re_end.h>
     14#include <re/re_cc.h>
     15#include <re/re_seq.h>
     16#include <re/re_rep.h>
     17#include <re/re_intersect.h>
     18#include <re/re_assertion.h>
    1119#include "UCD/PropertyAliases.h"
    1220#include "UCD/PropertyObjects.h"
     
    2533
    2634namespace UCD {
     35
     36void generateGraphemeClusterBoundaryRule(Name * const &property) {
     37    // 3.1.1 Grapheme Cluster Boundary Rules
     38#define Behind(x) makeLookBehindAssertion(x)
     39#define Ahead(x) makeLookAheadAssertion(x)
     40
     41    RE * GCB_Control = makeName("gcb", "cn", Name::Type::UnicodeProperty);
     42    RE * GCB_CR = makeName("gcb", "cr", Name::Type::UnicodeProperty);
     43    RE * GCB_LF = makeName("gcb", "lf", Name::Type::UnicodeProperty);
     44    RE * GCB_Control_CR_LF = makeAlt({GCB_CR, GCB_LF});
     45
     46    // Break at the start and end of text.
     47    RE * GCB_1 = makeStart();
     48    RE * GCB_2 = makeEnd();
     49    // Do not break between a CR and LF.
     50    RE * GCB_3 = makeSeq({Behind(GCB_CR), Ahead(GCB_LF)});
     51    // Otherwise, break before and after controls.
     52    RE * GCB_4 = Behind(GCB_Control_CR_LF);
     53    RE * GCB_5 = Ahead(GCB_Control_CR_LF);
     54    RE * GCB_1_5 = makeAlt({GCB_1, GCB_2, makeDiff(makeAlt({GCB_4, GCB_5}), GCB_3)});
     55
     56    RE * GCB_L = makeName("gcb", "l", Name::Type::UnicodeProperty);
     57    RE * GCB_V = makeName("gcb", "v", Name::Type::UnicodeProperty);
     58    RE * GCB_LV = makeName("gcb", "lv", Name::Type::UnicodeProperty);
     59    RE * GCB_LVT = makeName("gcb", "lvt", Name::Type::UnicodeProperty);
     60    RE * GCB_T = makeName("gcb", "t", Name::Type::UnicodeProperty);
     61    RE * GCB_RI = makeName("gcb", "ri", Name::Type::UnicodeProperty);
     62    // Do not break Hangul syllable sequences.
     63    RE * GCB_6 = makeSeq({Behind(GCB_L), Ahead(makeAlt({GCB_L, GCB_V, GCB_LV, GCB_LVT}))});
     64    RE * GCB_7 = makeSeq({Behind(makeAlt({GCB_LV, GCB_V})), Ahead(makeAlt({GCB_V, GCB_T}))});
     65    RE * GCB_8 = makeSeq({Behind(makeAlt({GCB_LVT, GCB_T})), Ahead(GCB_T)});
     66    // Do not break between regional indicator symbols.
     67    RE * GCB_8a = makeSeq({Behind(GCB_RI), Ahead(GCB_RI)});
     68    // Do not break before extending characters.
     69    RE * GCB_9 = Ahead(makeName("gcb", "ex", Name::Type::UnicodeProperty));
     70    // Do not break before SpacingMarks, or after Prepend characters.
     71    RE * GCB_9a = Ahead(makeName("gcb", "sm", Name::Type::UnicodeProperty));
     72    RE * GCB_9b = Behind(makeName("gcb", "pp", Name::Type::UnicodeProperty));
     73    RE * GCB_6_9b = makeAlt({GCB_6, GCB_7, GCB_8, GCB_8a, GCB_9, GCB_9a, GCB_9b});
     74    // Otherwise, break everywhere.
     75    RE * GCB_10 = makeSeq({Behind(makeAny()), Ahead(makeAny())});
     76
     77    //Name * gcb = makeName("gcb", Name::Type::UnicodeProperty);
     78    property->setDefinition(makeAlt({GCB_1_5, makeDiff(GCB_10, GCB_6_9b)}));
     79}
    2780
    2881bool resolvePropertyDefinition(Name * const property) {
     
    91144            Name * join = makeName("joincontrol", Name::Type::UnicodeProperty);
    92145            property->setDefinition(makeAlt({alnum, mark, conn, join}));
     146            return true;
     147        } else if (value == "GCB" || value == "NonGCB"){
     148            generateGraphemeClusterBoundaryRule(property);
    93149            return true;
    94150        }
  • icGREP/icgrep-devel/icgrep/UCD/resolve_properties.h

    r4817 r5091  
    2121};
    2222
     23void generateGraphemeClusterBoundaryRule(re::Name * const &property);
    2324bool resolvePropertyDefinition(re::Name * const property);
    2425std::string resolvePropertyFunction(re::Name * const property);
  • icGREP/icgrep-devel/icgrep/re/printer_re.cpp

    r5037 r5091  
    2020#include <re/re_intersect.h>
    2121#include <re/re_assertion.h>
    22 #include <re/re_grapheme_boundary.hpp>
    2322
    2423using namespace re;
     
    8685        retVal += ") ";
    8786    }
    88     else if (const GraphemeBoundary * g = dyn_cast<GraphemeBoundary>(re)) {
    89         retVal = "Grapheme";
    90         switch (g->getType()) {
    91             case GraphemeBoundary::Type::ClusterBoundary:
    92                 retVal += "Cluster"; break;
    93             case GraphemeBoundary::Type::LineBreakBoundary:
    94                 retVal += "LineBreak"; break;
    95             case GraphemeBoundary::Type::SentenceBoundary:
    96                 retVal += "Sentence"; break;
    97             case GraphemeBoundary::Type::WordBoundary:
    98                 retVal += "Word"; break;
    99         }
    100         retVal += "Boundary(";
    101         if (g->getExpression()) {
    102             retVal += PrintRE(g->getExpression());
    103         }
    104         retVal += ")";
    105     }
    10687    else if (isa<const End>(re))
    10788    {
  • icGREP/icgrep-devel/icgrep/re/re_analysis.cpp

    r5080 r5091  
    1111#include <re/re_intersect.h>
    1212#include <re/re_assertion.h>
    13 #include <re/re_grapheme_boundary.hpp>
    1413#include <iostream>
    1514#include <re/printer_re.h>
     
    137136            case Name::Type::Reference:
    138137                return getUnicodeUnitLengthRange(n->getDefinition());
     138            case Name::Type::ZeroWidth:
     139                return std::make_pair(0, 0);
    139140            case Name::Type::Unknown:
    140141                return std::make_pair(0, std::numeric_limits<int>::max());
    141142        }
    142     } else if (const GraphemeBoundary * gp = dyn_cast<GraphemeBoundary>(re)) {
    143         if (gp->getExpression()) {
    144             return getUnicodeUnitLengthRange(gp->getExpression());
    145         }
    146         return std::make_pair(0, 0);
    147     }
     143    }
    148144    return std::make_pair(1, 1);
    149145}
  • icGREP/icgrep-devel/icgrep/re/re_compiler.cpp

    r5083 r5091  
    1919#include <re/re_intersect.h>
    2020#include <re/re_assertion.h>
    21 #include <re/re_grapheme_boundary.hpp>
    2221#include <re/re_analysis.h>
    2322#include <re/re_memoizer.hpp>
     
    176175
    177176RE * RE_Compiler::resolveUnicodeProperties(RE * re) {
    178     Name * graphemeClusterRule = nullptr;
     177    Name * ZeroWidth = nullptr;
    179178    UCD::UCDCompiler::NameMap nameMap;
    180179    std::unordered_set<Name *> visited;
    181     nameMap = resolveNames(re, graphemeClusterRule);
     180    nameMap = resolveNames(re, ZeroWidth);
    182181   
    183182    if (LLVM_LIKELY(nameMap.size() > 0)) {
     
    196195
    197196    // Now precompile any grapheme segmentation rules
    198     if (graphemeClusterRule) {
    199         auto gcb = compileName(graphemeClusterRule, mPB);
    200         mCompiledName.insert(std::make_pair(graphemeClusterRule, gcb));
     197    if (ZeroWidth) {
     198        auto gcb = compileName(ZeroWidth, mPB);
     199        mCompiledName.insert(std::make_pair(ZeroWidth, gcb));
    201200    }
    202201    return re;
     
    242241    } else if (isa<End>(re)) {
    243242        return compileEnd(marker, pb);
    244     } else if (isa<GraphemeBoundary>(re)) {
    245         return compileGraphemeBoundary(cast<GraphemeBoundary>(re), marker, pb);
    246243    }
    247244    throw std::runtime_error("RE Compiler failed to process " + Printer_RE::PrintRE(re));
     
    270267        nameMarker.stream = pb.createAnd(markerVar(nextPos), markerVar(nameMarker), name->getName());
    271268        return nameMarker;
    272     }
    273     else {
     269    } else if (name->getType() == Name::Type::ZeroWidth) {
     270        RE * zerowidth = name->getDefinition();
     271        MarkerType zero = compile(zerowidth, pb);
     272        AlignMarkers(marker, zero, pb);
     273        PabloAST * ze = markerVar(zero);
     274        const std::string value = name->getName();
     275        if (value == "NonGCB") {
     276            ze = pb.createNot(ze);
     277        }
     278        return makeMarker(markerPos(marker), pb.createAnd(markerVar(marker), ze, "zerowidth"));
     279    } else {
    274280        return process(name->getDefinition(), marker, pb);
    275281    }
     
    574580}
    575581
    576 inline MarkerType RE_Compiler::compileGraphemeBoundary(GraphemeBoundary * gb, MarkerType marker, pablo::PabloBuilder & pb) {
     582/*inline MarkerType RE_Compiler::compileGraphemeBoundary(GraphemeBoundary * gb, MarkerType marker, pablo::PabloBuilder & pb) {
    577583    auto f = mCompiledName.find(gb->getBoundaryRule());
    578584    assert ("Internal error: failed to locate grapheme boundary rule!" && (f != mCompiledName.end()));
     
    592598    }
    593599    return marker;
    594 }
     600}*/
    595601
    596602inline MarkerType RE_Compiler::AdvanceMarker(MarkerType marker, const MarkerPosition newpos, PabloBuilder & pb) {
  • icGREP/icgrep-devel/icgrep/re/re_compiler.h

    r5045 r5091  
    8383    RE * resolveUnicodeProperties(RE * re);
    8484
    85     Name * generateGraphemeClusterBoundaryRule();
    8685    MarkerType compileName(Name * name, pablo::PabloBuilder & pb);
    8786    MarkerType compileAny(const MarkerType m, pablo::PabloBuilder & pb);
    8887    MarkerType compileStart(const MarkerType marker, pablo::PabloBuilder & pb);
    8988    MarkerType compileEnd(const MarkerType marker, pablo::PabloBuilder & pb);
    90     MarkerType compileGraphemeBoundary(GraphemeBoundary *gb, MarkerType marker, pablo::PabloBuilder & pb);
    9189
    9290    MarkerType AdvanceMarker(MarkerType marker, const MarkerPosition newpos, pablo::PabloBuilder & pb);
     
    9694
    9795    cc::CC_Compiler &                               mCCCompiler;
    98     pablo::PabloAST *                                 mLineBreak;
     96    pablo::PabloAST *                               mLineBreak;
    9997    pablo::PabloAST *                               mCRLF;
    10098    pablo::PabloAST *                               mAny;
  • icGREP/icgrep-devel/icgrep/re/re_name.h

    r5080 r5091  
    2727        , Capture
    2828        , Reference
     29        , ZeroWidth
    2930        , Unknown
    3031    };
     
    4344    friend Name * makeCapture(const std::string & name, RE * captured);
    4445    friend Name * makeReference(const std::string & name, RE * captureName);
     46    friend Name * makeZeroWidth(const std::string & name, RE * zerowidth);
    4547    friend Name * makeName(CC * const cc);
    4648    friend Name * makeName(const std::string &, const Type);
     
    168170}
    169171
     172inline Name * makeZeroWidth(const std::string & name, RE * zerowidth = NULL) {
     173    return new Name(nullptr, 0, name.c_str(), name.length(), Name::Type::ZeroWidth, zerowidth);
     174}
    170175}
    171176
  • icGREP/icgrep-devel/icgrep/re/re_name_resolve.cpp

    r5083 r5091  
    1010#include <re/re_intersect.h>
    1111#include <re/re_assertion.h>
    12 #include <re/re_grapheme_boundary.hpp>
    1312#include <re/re_analysis.h>
    1413#include <re/re_memoizer.hpp>
     
    3029}
    3130
    32 Name * generateGraphemeClusterBoundaryRule() {
    33     // 3.1.1 Grapheme Cluster Boundary Rules
    34     #define Behind(x) makeLookBehindAssertion(x)
    35     #define Ahead(x) makeLookAheadAssertion(x)
    36 
    37     RE * GCB_Control = makeName("gcb", "cn", Name::Type::UnicodeProperty);
    38     RE * GCB_CR = makeName("gcb", "cr", Name::Type::UnicodeProperty);
    39     RE * GCB_LF = makeName("gcb", "lf", Name::Type::UnicodeProperty);
    40     RE * GCB_Control_CR_LF = makeAlt({GCB_CR, GCB_LF});
    41 
    42     // Break at the start and end of text.
    43     RE * GCB_1 = makeStart();
    44     RE * GCB_2 = makeEnd();
    45     // Do not break between a CR and LF.
    46     RE * GCB_3 = makeSeq({Behind(GCB_CR), Ahead(GCB_LF)});
    47     // Otherwise, break before and after controls.
    48     RE * GCB_4 = Behind(GCB_Control_CR_LF);
    49     RE * GCB_5 = Ahead(GCB_Control_CR_LF);
    50     RE * GCB_1_5 = makeAlt({GCB_1, GCB_2, makeDiff(makeAlt({GCB_4, GCB_5}), GCB_3)});
    51 
    52     RE * GCB_L = makeName("gcb", "l", Name::Type::UnicodeProperty);
    53     RE * GCB_V = makeName("gcb", "v", Name::Type::UnicodeProperty);
    54     RE * GCB_LV = makeName("gcb", "lv", Name::Type::UnicodeProperty);
    55     RE * GCB_LVT = makeName("gcb", "lvt", Name::Type::UnicodeProperty);
    56     RE * GCB_T = makeName("gcb", "t", Name::Type::UnicodeProperty);
    57     RE * GCB_RI = makeName("gcb", "ri", Name::Type::UnicodeProperty);
    58     // Do not break Hangul syllable sequences.
    59     RE * GCB_6 = makeSeq({Behind(GCB_L), Ahead(makeAlt({GCB_L, GCB_V, GCB_LV, GCB_LVT}))});
    60     RE * GCB_7 = makeSeq({Behind(makeAlt({GCB_LV, GCB_V})), Ahead(makeAlt({GCB_V, GCB_T}))});
    61     RE * GCB_8 = makeSeq({Behind(makeAlt({GCB_LVT, GCB_T})), Ahead(GCB_T)});
    62     // Do not break between regional indicator symbols.
    63     RE * GCB_8a = makeSeq({Behind(GCB_RI), Ahead(GCB_RI)});
    64     // Do not break before extending characters.
    65     RE * GCB_9 = Ahead(makeName("gcb", "ex", Name::Type::UnicodeProperty));
    66     // Do not break before SpacingMarks, or after Prepend characters.
    67     RE * GCB_9a = Ahead(makeName("gcb", "sm", Name::Type::UnicodeProperty));
    68     RE * GCB_9b = Behind(makeName("gcb", "pp", Name::Type::UnicodeProperty));
    69     RE * GCB_6_9b = makeAlt({GCB_6, GCB_7, GCB_8, GCB_8a, GCB_9, GCB_9a, GCB_9b});
    70     // Otherwise, break everywhere.
    71     RE * GCB_10 = makeSeq({Behind(makeAny()), Ahead(makeAny())});
    72 
    73     Name * gcb = makeName("gcb", Name::Type::UnicodeProperty);
    74     gcb->setDefinition(makeAlt({GCB_1_5, makeDiff(GCB_10, GCB_6_9b)}));
    75     return gcb;
    76 }
    77 
    78 Name * graphemeClusterRule = nullptr;
     31Name * ZeroWidth = nullptr;
    7932
    8033RE * resolve(RE * re) {
     
    8538            if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
    8639                name->setDefinition(resolve(name->getDefinition()));
    87             } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty)) {
     40            } else if (LLVM_LIKELY(name->getType() == Name::Type::UnicodeProperty || name->getType() == Name::Type::ZeroWidth)) {
    8841                if (UCD::resolvePropertyDefinition(name)) {
    89                     resolve(name->getDefinition());
     42                    if (name->getType() == Name::Type::ZeroWidth) {
     43                        ZeroWidth = name;
     44                    }
     45                    resolve(name->getDefinition());
    9046                } else {
    9147                    #ifndef DISABLE_PREGENERATED_UCD_FUNCTIONS
     
    160116            return resolve(makeName("intersect", intersectCC(lh, rh)));
    161117        }
    162     } else if (GraphemeBoundary * gb = dyn_cast<GraphemeBoundary>(re)) {
    163         if (LLVM_LIKELY(gb->getBoundaryRule() == nullptr)) {
    164             switch (gb->getType()) {
    165                 case GraphemeBoundary::Type::ClusterBoundary:
    166                     if (graphemeClusterRule == nullptr) {
    167                         graphemeClusterRule = cast<Name>(resolve(generateGraphemeClusterBoundaryRule()));
    168                     }
    169                     gb->setBoundaryRule(graphemeClusterRule);
    170                     break;
    171                 default:
    172                     throw std::runtime_error("Only grapheme cluster boundary rules are supported in icGrep 1.0");
    173             }
    174         }
    175         if (gb->getExpression()) {
    176             resolve(gb->getExpression());
    177         }
    178118    }
    179119    return re;
     
    211151        gather(cast<Intersect>(re)->getLH());
    212152        gather(cast<Intersect>(re)->getRH());
    213     } else if (isa<GraphemeBoundary>(re)) {
    214         if (cast<GraphemeBoundary>(re)->getExpression()) {
    215             gather(cast<GraphemeBoundary>(re)->getExpression());
    216         }
    217         gather(cast<GraphemeBoundary>(re)->getBoundaryRule());
    218     }
     153    }
    219154}
    220155   
    221 UCD::UCDCompiler::NameMap resolveNames(RE * re, Name * &Rule) {
     156UCD::UCDCompiler::NameMap resolveNames(RE * re, Name * &zerowidth) {
    222157
    223     graphemeClusterRule = nullptr;
     158    ZeroWidth = nullptr;
    224159    re = resolve(re);
    225160    gather(re);
    226     Rule = graphemeClusterRule;
     161    zerowidth = ZeroWidth;
    227162   
    228163    return nameMap;
  • icGREP/icgrep-devel/icgrep/re/re_name_resolve.h

    r5083 r5091  
    77#include <UCD/ucd_compiler.hpp>
    88namespace re {
    9     UCD::UCDCompiler::NameMap resolveNames(RE * re, Name * &Rule);
     9    UCD::UCDCompiler::NameMap resolveNames(RE * re, Name * &zerowidth);
    1010    Name * resolveOtherNames(RE * re);
    1111    Name * generateGraphemeClusterBoundaryRule();
  • icGREP/icgrep-devel/icgrep/re/re_nullable.cpp

    r4841 r5091  
    55#include <re/re_alt.h>
    66#include <re/re_rep.h>
    7 #include <re/re_grapheme_boundary.hpp>
    87#include <re/re_name.h>
    98
  • icGREP/icgrep-devel/icgrep/re/re_parser.cpp

    r5080 r5091  
    1515#include <re/re_intersect.h>
    1616#include <re/re_assertion.h>
    17 #include <re/re_grapheme_boundary.hpp>
    1817#include <re/printer_re.h>
    1918#include <UCD/resolve_properties.h>
     
    3938    parser.fModeFlagSet = initialFlags;
    4039    parser.fNested = false;
     40    parser.fGraphemeBoundaryPending = false;
    4141    parser.mCaptureGroupCount = 0;
    4242    RE * re = parser.parse_RE();
     
    5050    : fModeFlagSet(0)
    5151    , fNested(false)
     52    , fGraphemeBoundaryPending(false)
    5253    , mCursor(regular_expression)
    5354    , mCaptureGroupCount(0)
     
    9091        RE * re = parse_next_item();
    9192        if (re == nullptr) {
     93            if (fGraphemeBoundaryPending == true) {
     94                seq.push_back(makeZeroWidth("GCB"));
     95                fGraphemeBoundaryPending = false;
     96            }
    9297            break;
    9398        }
     
    99104
    100105RE * RE_Parser::parse_next_item() {
     106    RE * re = nullptr;
    101107    if (mCursor.more()) {       
    102108        switch (*mCursor) {
     
    128134            case '[':
    129135                mCursor++;
    130                 return parse_charset();
     136                re = parse_charset();
     137                if ((fModeFlagSet & ModeFlagType::GRAPHEME_CLUSTER_MODE) != 0) {
     138                    re = makeSeq({re, makeZeroWidth("GCB")});
     139                }
     140                return re;
    131141            case '.': // the 'any' metacharacter
    132142                mCursor++;
     
    136146                return parse_escaped();
    137147            default:
    138                 return createCC(parse_utf8_codepoint());
     148                re = createCC(parse_utf8_codepoint());
     149                if ((fModeFlagSet & ModeFlagType::GRAPHEME_CLUSTER_MODE) != 0) {
     150                    fGraphemeBoundaryPending = true;
     151                }
     152                return re;
    139153        }
    140154    }
     
    280294            re = makeRep(re, lb, ub);
    281295        }
    282     }
    283     if ((fModeFlagSet & ModeFlagType::GRAPHEME_CLUSTER_MODE) != 0) {
    284         re = makeGraphemeClusterBoundary(GraphemeBoundary::Sense::Positive, re);
    285296    }
    286297    return re;
     
    361372                switch (*++mCursor) {
    362373                    case 'g':
    363                         re = makeGraphemeClusterBoundary(complemented ? GraphemeBoundary::Sense::Negative : GraphemeBoundary::Sense::Positive);
     374                        re = complemented ? makeZeroWidth("NonGCB") : makeZeroWidth("GCB");
    364375                        break;
    365376                    case 'w': throw ParseFailure("\\b{w} not yet supported.");
     
    422433            // to get to the next extended grapheme cluster boundary.
    423434            ++mCursor;
    424             // return makeSeq({makeRep(makeAny(), 1, Rep::UNBOUNDED_REP), makeGraphemeClusterBoundary()});
    425             return makeGraphemeClusterBoundary(GraphemeBoundary::Sense::Positive, makeAny());
     435            return makeSeq({makeAny(), makeRep(makeSeq({makeZeroWidth("NonGCB"), makeAny()}), 0, Rep::UNBOUNDED_REP), makeZeroWidth("GCB")});
    426436        case 'N':
    427437            if (*++mCursor != '{') {
  • icGREP/icgrep-devel/icgrep/re/re_parser.h

    r5080 r5091  
    146146    Name * makeWhitespaceSet();
    147147    Name * makeWordSet();
    148 
     148   
    149149    Name * createName(std::string && value);
    150150    Name * createName(std::string && prop, std::string && value);
     
    173173    ModeFlagSet                 fModeFlagSet;
    174174    bool                        fNested;
     175    bool                        fGraphemeBoundaryPending;
    175176    Cursor                      mCursor;
    176177    unsigned                    mCaptureGroupCount;
  • icGREP/icgrep-devel/icgrep/re/re_re.h

    r5037 r5091  
    3434class SymDiff;
    3535class Union;
    36 class GraphemeBoundary;
    3736
    3837class RE {
     
    5554        , SymDiff
    5655        , Union
    57         , GraphemeBoundary
    5856    };
    5957    inline ClassTypeId getClassTypeId() const {
  • icGREP/icgrep-devel/icgrep/re/re_simplifier.cpp

    r4846 r5091  
    1111#include <re/re_intersect.h>
    1212#include <re/re_assertion.h>
    13 #include <re/re_grapheme_boundary.hpp>
    1413#include <re/re_analysis.h>
    1514#include <algorithm>
     
    3837    } else if (Rep * rep = dyn_cast<Rep>(re)) {
    3938        RE * expr = simplify(rep->getRE());
    40         if (GraphemeBoundary * gp = dyn_cast<GraphemeBoundary>(expr)) {
    41             if (gp->getExpression() && isUnicodeUnitLength(gp->getExpression())) {
    42                 rep->setRE(gp->getExpression());
    43                 gp->setExpression(rep);
    44                 return gp;
    45             }
    46         }
    4739        re = makeRep(expr, rep->getLB(), rep->getUB());
    4840    } else if (Diff * diff = dyn_cast<Diff>(re)) {
     
    5042    } else if (Intersect * e = dyn_cast<Intersect>(re)) {
    5143        re = makeIntersect(simplify(e->getLH()), e->getRH());
    52     } else if (GraphemeBoundary * gp = dyn_cast<GraphemeBoundary>(re)) {
    53         if (gp->getExpression() && isa<GraphemeBoundary>(gp->getExpression())) {
    54             re = gp->getExpression();
    55         }
    56     }
     44    }
    5745    return re;
    5846}
Note: See TracChangeset for help on using the changeset viewer.