Changeset 4182 for icGREP


Ignore:
Timestamp:
Sep 21, 2014, 10:25:56 AM (5 years ago)
Author:
nmedfort
Message:

RE Parser modification to use ParseFailure? exceptions; removed the list reversal within Alt and Seq constructors and adjusted the functions that relied on it occurring.

Location:
icGREP/icgrep-devel/icgrep
Files:
4 added
4 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/CMakeLists.txt

    r4152 r4182  
    4949add_library(PabloADT pe_advance.cpp  pe_all.cpp  pe_and.cpp pe_call.cpp pe_charclass.cpp  pe_matchstar.cpp pe_scanthru.cpp pe_not.cpp  pe_or.cpp  pe_pabloe.cpp  pe_sel.cpp  pe_var.cpp  pe_xor.cpp ps_assign.cpp  ps_if.cpp  ps_pablos.cpp  ps_while.cpp printer_pablos.cpp)
    5050
    51 add_library(RegExpADT re_alt.cpp  re_cc.cpp  re_end.cpp  re_name.cpp re_parser.cpp  re_re.cpp  re_rep.cpp  re_seq.cpp  re_start.cpp parsefailure.cpp  parseresult.cpp  parsesuccess.cpp printer_re.cpp)
     51add_library(RegExpADT re_alt.cpp  re_cc.cpp  re_end.cpp  re_name.cpp re_parser.cpp  re_re.cpp  re_rep.cpp  re_seq.cpp  re_start.cpp parsefailure.cpp  printer_re.cpp)
    5252
    5353
  • icGREP/icgrep-devel/icgrep/cc_compiler.cpp

    r4132 r4182  
    106106{
    107107
    108     if (Alt* re_alt = dynamic_cast<Alt*>(re))
    109     {
    110         std::list<RE*>::iterator it;
    111         for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
    112         {
    113             process_re(*it);
    114         }
    115     }
    116     else if (CC* re_cc = dynamic_cast<CC*>(re))
    117     {
     108    if (Alt* re_alt = dynamic_cast<Alt*>(re)) {
     109        for (RE * re : *re_alt) {
     110            process_re(re);
     111        }
     112    }
     113    else if (CC* re_cc = dynamic_cast<CC*>(re)) {
    118114        cc2pablos(re_cc);
    119115    }
    120     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    121     {
     116    else if (Rep* re_rep = dynamic_cast<Rep*>(re)) {
    122117        process_re(re_rep->getRE());
    123118    }
    124     else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    125     {
    126         std::list<RE*>::iterator it;
    127         for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
    128         {
    129             process_re(*it);
     119    else if (Seq* re_seq = dynamic_cast<Seq*>(re)) {
     120        for (RE * re : *re_seq) {
     121            process_re(re);
    130122        }
    131123    }
  • icGREP/icgrep-devel/icgrep/parsefailure.cpp

    r3850 r4182  
    77#include "parsefailure.h"
    88
    9 ParseFailure::ParseFailure(std::string msg)
     9ParseFailure::ParseFailure(const std::string && msg) noexcept
     10: _msg(msg)
    1011{
    11     mErrorMsg = msg;
     12
    1213}
    1314
    14 ParseFailure::~ParseFailure(){}
     15ParseFailure::~ParseFailure() noexcept { }
    1516
    16 std::string ParseFailure::getErrorMsg()
    17 {
    18     return mErrorMsg;
     17const char* ParseFailure::what() const noexcept {
     18    return _msg.c_str();
    1919}
  • icGREP/icgrep-devel/icgrep/parsefailure.h

    r3850 r4182  
    88#define PARSEFAILURE_H
    99
    10 #include "parseresult.h"
    1110#include <string>
     11#include <stdexcept>
    1212
    13 class ParseFailure : public ParseResult
    14 {
     13class ParseFailure : public std::exception {
    1514public:
    16     ParseFailure(std::string msg);
    17     ~ParseFailure();
    18     std::string getErrorMsg();
     15    ParseFailure(const std::string && msg) noexcept;
     16    virtual ~ParseFailure() noexcept;
     17    virtual const char* what() const noexcept;
    1918private:
    20     std::string mErrorMsg;
     19    inline ParseFailure() noexcept {}
     20    const std::string _msg;
     21};
     22
     23class NoRegularExpressionFound : public ParseFailure {
     24public:
     25    NoRegularExpressionFound() noexcept : ParseFailure("No regular expression found!") { }
     26    virtual ~NoRegularExpressionFound() noexcept {}
     27};
     28
     29class IncompleteRegularExpression : public ParseFailure {
     30public:
     31    IncompleteRegularExpression() noexcept : ParseFailure("Incomplete regular expression!") { }
     32    virtual ~IncompleteRegularExpression() noexcept {}
     33};
     34
     35class UnclosedCharacterClass : public ParseFailure {
     36public:
     37    UnclosedCharacterClass() noexcept : ParseFailure("Unclosed character class!") { }
     38    virtual ~UnclosedCharacterClass() noexcept {}
     39};
     40
     41class InvalidUTF8Encoding : public ParseFailure {
     42public:
     43    InvalidUTF8Encoding() noexcept : ParseFailure("Invalid UTF-8 encoding!") { }
     44    virtual ~InvalidUTF8Encoding() noexcept {}
     45};
     46
     47class UnclosedUnicodeCharacterClass : public ParseFailure {
     48public:
     49    UnclosedUnicodeCharacterClass() noexcept : ParseFailure("Unclosed Unicode character class!") { }
     50    virtual ~UnclosedUnicodeCharacterClass() noexcept {}
     51};
     52
     53class BadLowerBound : public ParseFailure {
     54public:
     55    BadLowerBound() noexcept : ParseFailure("Bad lower bound!") { }
     56    virtual ~BadLowerBound() noexcept {}
     57};
     58
     59class BadUpperBound : public ParseFailure {
     60public:
     61    BadUpperBound() noexcept : ParseFailure("Bad upper bound!") { }
     62    virtual ~BadUpperBound() noexcept {}
    2163};
    2264
  • icGREP/icgrep-devel/icgrep/pbix_compiler.cpp

    r4129 r4182  
    2929                cg_state.newsym = gs_retVal;
    3030
    31                 std::list<RE*>::iterator endit;
    32                 endit = seq->GetREList()->end();
     31                auto endit = seq->end();
    3332                --endit;
    34                 std::list<RE*>::iterator it;
    35                 for (it = seq->GetREList()->begin(); it != seq->GetREList()->end(); ++it)
     33
     34                for (auto it = seq->begin(); it != seq->end(); ++it)
    3635                {
    3736                    Name* name = dynamic_cast<Name*>(*it);
     
    139138        //std::cout << "\n" << "(" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << std::endl;
    140139    }
    141     else if (Start* start = dynamic_cast<Start*>(re))
     140    else if (dynamic_cast<Start*>(re))
    142141    {
    143142        std::string gs_retVal = symgen.gensym("start_of_line_marker");
     
    145144        cg_state.newsym = gs_retVal;
    146145    }
    147     else if (End* end = dynamic_cast<End*>(re))
     146    else if (dynamic_cast<End*>(re))
    148147    {
    149148        std::string gs_retVal = symgen.gensym("end_of_line_marker");
     
    153152    else if (Seq* seq = dynamic_cast<Seq*>(re))
    154153    {
    155         std::list<RE*>::iterator it = seq->GetREList()->begin();
    156         if (it != seq->GetREList()->end())
    157         {
    158             cg_state = Seq_helper(seq->GetREList(), it, cg_state);
    159         }
    160     //cout << "\n" << "Seq => (" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << endl;
     154        if (!seq->empty())
     155        {
     156            cg_state = Seq_helper(seq, seq->begin(), cg_state);
     157        }
    161158    }
    162159    else if (Alt* alt = dynamic_cast<Alt*>(re))
    163160    {
    164         if (alt->GetREList() == 0)
     161        if (alt->empty())
    165162        {
    166163
     
    171168        else
    172169        {
    173             if (alt->GetREList()->size() == 1)
    174             {
    175                 cg_state = re2pablo_helper(alt->GetREList()->front(), cg_state);
     170            if (alt->size() == 1)
     171            {
     172                cg_state = re2pablo_helper(alt->back(), cg_state);
    176173            }
    177174            else
    178175            {
    179                 std::list<RE*>::iterator it = alt->GetREList()->begin();
    180                 cg_state = Alt_helper(alt->GetREList(), it, cg_state);
    181             }
    182         }
    183     //cout << "\n" << "Alt => (" << StatementPrinter::PrintStmts(cg_state) << ")" << "\n" << endl;
     176                cg_state = Alt_helper(alt, alt->begin(), cg_state);
     177            }
     178        }
     179
    184180    }
    185181    else if (Rep* rep = dynamic_cast<Rep*>(re))
    186182    {
    187         if ((dynamic_cast<Name*>(rep->getRE()) != 0) && (rep->getLB() == 0) && (rep->getUB()== unboundedRep))
     183        if ((dynamic_cast<Name*>(rep->getRE()) != 0) && (rep->getLB() == 0) && (rep->getUB()== UNBOUNDED_REP))
    188184        {
    189185            Name* rep_name = dynamic_cast<Name*>(rep->getRE());
     
    217213            cg_state.newsym = gs_retVal;
    218214        }
    219         else if (rep->getUB() == unboundedRep)
    220         {
    221             cg_state = UnboundedRep_helper(rep->getRE(), rep->getLB(), cg_state);
    222         }
    223         else if (rep->getUB() != unboundedRep)
    224         {
    225             cg_state = BoundedRep_helper(rep->getRE(), rep->getLB(), rep->getUB(), cg_state);
    226         }
    227     }
    228 
    229     return cg_state;
    230 }
    231 
    232 
    233 CodeGenState Pbix_Compiler::Seq_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state)
     215        else if (rep->getUB() == UNBOUNDED_REP)
     216        {
     217            cg_state = UnboundedRep_helper(rep->getRE(), rep->getLB(), cg_state);
     218        }
     219        else if (rep->getUB() != UNBOUNDED_REP)
     220        {
     221            cg_state = BoundedRep_helper(rep->getRE(), rep->getLB(), rep->getUB(), cg_state);
     222        }
     223    }
     224
     225    return cg_state;
     226}
     227
     228
     229CodeGenState Pbix_Compiler::Seq_helper(Vector *lst, const_iterator it, CodeGenState cg_state)
    234230{
    235231    if (it != lst->end())
     
    242238}
    243239
    244 CodeGenState Pbix_Compiler::Alt_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state)
     240CodeGenState Pbix_Compiler::Alt_helper(Vector* lst, const_iterator it, CodeGenState cg_state)
    245241{
    246242    CodeGenState t1_cg_state = re2pablo_helper(*it, cg_state);
     
    334330        else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    335331        {
    336             std::list<RE*>::iterator it;
    337             for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
     332            for (auto it = re_seq->begin(); it != re_seq->end(); ++it)
    338333            {
    339334                found = unicode_re_helper(*it, found);
     
    343338        else if (Alt* re_alt = dynamic_cast<Alt*>(re))
    344339        {
    345             std::list<RE*>::iterator it;
    346             for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
     340            for (auto it = re_alt->begin(); it != re_alt->end(); ++it)
    347341            {
    348342                found = unicode_re_helper(*it, found);
  • icGREP/icgrep-devel/icgrep/pbix_compiler.h

    r4129 r4182  
    5656class Pbix_Compiler
    5757{
     58    typedef RE::Vector              Vector;
     59    typedef Vector::const_iterator  const_iterator;
     60
    5861public:
    5962    Pbix_Compiler(std::map<std::string, std::string> name_map);
     
    6265private:
    6366    CodeGenState re2pablo_helper(RE *re, CodeGenState cg_state);
    64     CodeGenState Seq_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state);
    65     CodeGenState Alt_helper(std::list<RE*>* lst, std::list<RE*>::const_iterator it, CodeGenState cg_state);
     67    CodeGenState Seq_helper(Vector * lst, const_iterator it, CodeGenState cg_state);
     68    CodeGenState Alt_helper(Vector * lst, const_iterator it, CodeGenState cg_state);
    6669    CodeGenState UnboundedRep_helper(RE* repeated, int lb, CodeGenState cg_state);
    6770    CodeGenState BoundedRep_helper(RE* repeated, int lb, int ub, CodeGenState cg_state);
  • icGREP/icgrep-devel/icgrep/printer_re.cpp

    r3984 r4182  
    88
    99
    10 std::string Printer_RE::PrintRE(RE* re)
     10std::string Printer_RE::PrintRE(RE * re)
    1111{
    1212    std::string retVal = "";
    1313
    14     if (Alt* re_alt = dynamic_cast<Alt*>(re))
     14    if (re == nullptr) {
     15        retVal = "--> RE NullPtr! <--";
     16    }
     17    else if (Alt* re_alt = dynamic_cast<Alt*>(re))
    1518    {
    1619        retVal += "(Alt[";
    17 
    18         std::list<RE*>::iterator it;
    19         for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
    20         {
    21             retVal += PrintRE(*it) + ",";
     20        for (RE * re : *re_alt) {
     21            retVal += PrintRE(re) + ",";
    2222        }
    2323        retVal = retVal.substr(0, retVal.size() - 1);
     
    3030        retVal += "\" ";
    3131
    32         std::vector<CharSetItem> items = re_cc->getItems();
    33         std::vector<CharSetItem>::iterator it;
    34         for (it = items.begin(); it != items.end(); ++it)
     32        for (const CharSetItem & item : re_cc->getItems())
    3533        {
    3634            retVal += "[";
    37             retVal += std::to_string(it->lo_codepoint) + ",";
    38             retVal += std::to_string(it->hi_codepoint);
     35            retVal += std::to_string(item.lo_codepoint) + ",";
     36            retVal += std::to_string(item.hi_codepoint);
    3937            retVal += "]";
    4038        }
    41 
    42         //std::string member = (re_cc->is_member(47) ? "True" : "False");
    43         //retVal += " is codepoint 47 a member: " + member;
    44 
    45 /*
    46         retVal += "CC \"";
    47         retVal += re_cc->getName();
    48         retVal += "\" ";
    49 
    50         retVal += " Removed: 100 ";
    51         re_cc->remove1(100);
    52         //re_cc->remove_range(40,50);
    53 
    54         std::vector<CharSetItem> r_items = re_cc->getItems();
    55         std::vector<CharSetItem>::iterator r_it;
    56         for (r_it = r_items.begin(); r_it != r_items.end(); ++r_it)
    57         {
    58             retVal += "[";
    59             retVal += std::to_string(r_it->lo_codepoint) + ",";
    60             retVal += std::to_string(r_it->hi_codepoint);
    61             retVal += "]";
    62         }
    63 */
    6439    }
    6540    else if (Name* re_name = dynamic_cast<Name*>(re))
     
    6944        retVal += "\" ";
    7045    }
    71     else if (End* re_end = dynamic_cast<End*>(re))
     46    else if (dynamic_cast<End*>(re))
    7247    {
    7348        retVal += "End";
     
    7651    {
    7752        retVal += "Rep("  + PrintRE(re_rep->getRE()) + "," + std::to_string(re_rep->getLB()) + ",";
    78         retVal += (re_rep->getUB() == unboundedRep ? "Unbounded" : "UpperBound(" + std::to_string(re_rep->getUB()) + ")");
     53        retVal += (re_rep->getUB() == UNBOUNDED_REP ? "Unbounded" : "UpperBound(" + std::to_string(re_rep->getUB()) + ")");
    7954    }
    8055    else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    8156    {
    8257        retVal += "(Seq[";
    83         std::list<RE*>::iterator it;
    84         for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
    85         {
    86             retVal += PrintRE(*it) + ",";
     58        for (RE * re : *re_seq) {
     59            retVal += PrintRE(re) + ",";
    8760        }
    8861        retVal = retVal.substr(0, retVal.size() - 1);
    8962        retVal += "])";
    9063    }
    91     else if (Start* re_start = dynamic_cast<Start*>(re))
     64    else if (dynamic_cast<Start*>(re))
    9265    {
    9366        retVal += "Start";
  • icGREP/icgrep-devel/icgrep/re_alt.cpp

    r3914 r4182  
    99Alt::Alt()
    1010{
    11     mList = new std::list<RE*>();
     11
    1212}
    1313
    14 Alt::Alt(std::list<RE*>* lst)
     14Alt::Alt(iterator begin, iterator end)
     15: std::vector<RE*>(begin, end)
    1516{
    16     mList = new std::list<RE*>();
    17     std::list<RE*>::iterator it;
    18     it=lst->begin();
    19     mList->assign(it, lst->end());
    20     std::reverse(mList->begin(), mList->end());
    21 }
    2217
    23 Alt::Alt(std::list<RE*> lst)
    24 {
    25     mList = new std::list<RE*>();
    26     std::list<RE*>::iterator it;
    27     it=lst.begin();
    28     mList->assign(it, lst.end());
    29     std::reverse(mList->begin(), mList->end());
    3018}
    3119
    3220Alt::~Alt()
    3321{
    34     while(!mList->empty()) delete mList->back(), mList->pop_back();
    35     delete mList;
     22    for (RE * re : *this) {
     23        delete re;
     24    }
    3625}
    37 
    38 std::list<RE*>* Alt::GetREList()
    39 {
    40     return mList;
    41 }
    42 
    43 void Alt::AddREListItem(RE* re)
    44 {
    45     mList->push_back(re);
    46 }
    47 
    48 
  • icGREP/icgrep-devel/icgrep/re_alt.h

    r3914 r4182  
    1313
    1414
    15 class Alt : public RE
    16 {
     15class Alt : public RE, public RE::Vector {
    1716public:
    18     Alt();
    19     Alt(std::list<RE*>* lst);
    20     Alt(std::list<RE*> lst);
    21     ~Alt();
    22     std::list<RE*>* GetREList();
    23     void AddREListItem(RE *re);
    24 private:
    25     std::list<RE*>* mList;
     17    typedef RE::Vector Vector;
     18    Alt();   
     19    Alt(iterator begin, iterator end);
     20    virtual ~Alt();
    2621};
    2722
  • icGREP/icgrep-devel/icgrep/re_compiler.cpp

    r4132 r4182  
    66
    77#include "re_compiler.h"
     8#include "re_alt.h"
     9#include "re_cc.h"
     10#include "re_name.h"
     11#include "re_end.h"
     12#include "re_rep.h"
     13#include "re_seq.h"
     14#include "re_start.h"
     15#include "re_nullable.h"
     16#include "re_simplifier.h"
     17#include "re_reducer.h"
     18
     19#include "printer_pablos.h"
     20#include "printer_re.h"
     21
     22#include "utf8_encoder.h"
     23
     24#include "parsefailure.h"
     25#include "re_parser.h"
     26#include "cc_compiler.h"
     27
     28#include "pbix_compiler.h"
     29#include "symbol_generator.h"
     30
     31//FOR TESTING AND AND ANALYSIS
     32//#include "pbix_counter.h"
     33
    834
    935RE_Compiler::RE_Compiler(){}
     
    1743{
    1844    CC_Compiler cc_compiler(encoding, basis_pattern, gensym_pattern);
    19     ParseResult* parse_result = RE_Parser::parse_re(input_string);
    2045
    21     RE* re_ast = 0;
    22     if (ParseSuccess* success = dynamic_cast<ParseSuccess*>(parse_result))
     46//    std::cerr << "============================================================================" << std::endl;
     47//    std::cerr << input_string << std::endl;
     48//    std::cerr << "============================================================================" << std::endl;
     49
     50    RE* re_ast = nullptr;
     51    try
    2352    {
    24         re_ast = success->getRE();
     53        re_ast = RE_Parser::parse_re(input_string);
    2554    }
    26     else if (ParseFailure* failure = dynamic_cast<ParseFailure*>(parse_result))
     55    catch (ParseFailure failure)
    2756    {
    28         std::cout << failure->getErrorMsg() << std::endl;
     57        std::cerr << "REGEX PARSING FAILURE: " << failure.what() << std::endl;
    2958        exit(1);
    3059    }
    31     else
    32     {
    33         std::cout << "An unexepected parser error has occured!" << std::endl;
    34         exit(1);
    35     }
     60
     61
     62
     63
    3664
    3765    //Print to the terminal the AST that was generated by the parser before adding the UTF encoding:
     
    5684
    5785    //Optimization passes to simplify the AST.
    58     re_ast = RE_Simplifier::simplify(RE_Nullable::removeNullableSuffix(RE_Nullable::removeNullablePrefix(re_ast)));
     86    re_ast = RE_Nullable::removeNullablePrefix(re_ast);
     87
     88    re_ast = RE_Nullable::removeNullableSuffix(re_ast);
     89
     90    re_ast = RE_Simplifier::simplify(re_ast);
    5991
    6092    //Print to the terminal the AST that was generated by the simplifier.
     
    105137    CodeGenState re_subexpression_cg_state = pbix_compiler.compile_subexpressions(re_map);
    106138    //Print to the terminal the AST that was generated for the re subexpressions.
    107     //std::cout << "\n" << "Subexpressions: (" << StatementPrinter::PrintStmts(re_subexpression_cg_state) << ")" << std::endl;
     139    // std::cerr << "\n" << "Subexpressions: (" << StatementPrinter::PrintStmts(re_subexpression_cg_state) << ")" << std::endl;
    108140
    109141    CodeGenState re_cg_state = pbix_compiler.compile(re_ast);
    110142    //Print to the terminal the AST that was generated by the pararallel bit-stream compiler.
    111     //std::cout << "\n" << "(" << StatementPrinter::PrintStmts(re_cg_state) << ")" << "\n" << std::endl;
     143    // std::cerr << "\n" << "(" << StatementPrinter::PrintStmts(re_cg_state) << ")" << "\n" << std::endl;
    112144
    113145    //Print a count of the Pablo statements and expressions that are contained in the AST from the pbix compiler.
  • icGREP/icgrep-devel/icgrep/re_compiler.h

    r4132 r4182  
    1212//Regular Expressions
    1313#include "re_re.h"
    14 #include "re_alt.h"
    15 #include "re_cc.h"
    16 #include "re_name.h"
    17 #include "re_end.h"
    18 #include "re_rep.h"
    19 #include "re_seq.h"
    20 #include "re_start.h"
    21 #include "re_nullable.h"
    22 #include "re_simplifier.h"
    23 #include "re_reducer.h"
    24 
    25 #include "printer_pablos.h"
    26 #include "printer_re.h"
    27 
    28 #include "utf8_encoder.h"
    2914#include "utf_encoding.h"
    30 
    31 #include "parseresult.h"
    32 #include "parsesuccess.h"
    33 #include "parsefailure.h"
    34 #include "re_parser.h"
    35 #include "cc_compiler.h"
    36 
    37 #include "pbix_compiler.h"
    38 #include "symbol_generator.h"
    3915#include "llvm_gen.h"
    40 
    41 //FOR TESTING AND AND ANALYSIS
    42 //#include "pbix_counter.h"
    43 
    44 #include <fstream>
    45 #include <iostream>
    4616#include <string>
    47 #include <sstream>
    48 #include <vector>
    49 #include <ctype.h>
    5017
    5118struct processed_parsetree_results{
  • icGREP/icgrep-devel/icgrep/re_name.cpp

    r3992 r4182  
    2222}
    2323
    24 std::string Name::getName()
     24std::string Name::getName() const
    2525{
    2626    return mName;
    2727}
    2828
    29 bool Name::isNegated()
     29bool Name::isNegated() const
    3030{
    3131    return mNegated;
     
    4242}
    4343
    44 Name::Type Name::getType()
     44Name::Type Name::getType() const
    4545{
    4646    return mType;
  • icGREP/icgrep-devel/icgrep/re_name.h

    r3992 r4182  
    1313    Name(std::string name);
    1414    void setName(std::string name);
    15     std::string getName();
     15    std::string getName() const;
    1616    void setNegated(bool is_negated);
    17     bool isNegated();
     17    bool isNegated() const;
    1818    void setType(Type type);
    19     Type getType();
     19    Type getType() const;
    2020    ~Name();
    2121private:
  • icGREP/icgrep-devel/icgrep/re_nullable.cpp

    r4034 r4182  
    11#include "re_nullable.h"
     2#include "re_cc.h"
     3#include "re_start.h"
     4#include "re_end.h"
     5#include "re_alt.h"
     6#include "re_rep.h"
     7#include "re_simplifier.h"
    28
    39/*
     
    915*/
    1016
    11 RE* RE_Nullable::removeNullablePrefix(RE* re)
    12 {
    13     RE* retVal = 0;
    14 
    15     if (Seq* re_seq = dynamic_cast<Seq*>(re))
    16     {
    17         std::list<RE*>* re_list = re_seq->GetREList();
    18         std::list<RE*>* t1_list = new std::list<RE*>();
    19         t1_list->assign(re_list->begin(), re_list->end());
    20         Seq* new_seq = new Seq(removeNullableSeqPrefix(t1_list));
    21         new_seq->setType(re_seq->getType());
    22 
    23         return new_seq;
     17RE * RE_Nullable::removeNullablePrefix(RE* re) {
     18    if (Seq * re_seq = dynamic_cast<Seq*>(re)) {
     19        re = removeNullableSeqPrefix(re_seq);
    2420    }
    25     else if (Alt* re_alt = dynamic_cast<Alt*>(re))
    26     {
    27         Alt* new_alt = new Alt();
    28         std::list<RE*>::iterator it;
    29 
    30         for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
    31         {
    32             new_alt->AddREListItem(removeNullablePrefix(*it));
     21    else if (Alt * re_alt = dynamic_cast<Alt*>(re)) {
     22        Alt * new_alt = new Alt();
     23        for (RE * re : *re_alt) {
     24            new_alt->push_back(removeNullablePrefix(re));
    3325        }
    34 
    35         return new_alt;
     26        re = new_alt;
    3627    }
    37     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    38     {
    39         if ((re_rep->getLB() == 0) || (isNullable(re_rep->getRE())))
    40         {
    41             return new Seq();
     28    else if (Rep * re_rep = dynamic_cast<Rep*>(re)) {
     29        if ((re_rep->getLB() == 0) || (isNullable(re_rep->getRE()))) {
     30            re = new Seq();
    4231        }
    43         else if (hasNullablePrefix(re_rep->getRE()))
    44         {
    45             //std::cout << "removeNullablePrefix->Rep->hasNullablePrefix:" << std::endl;
    46             std::list<RE*>* seq_lst = new std::list<RE*>();
    47             seq_lst->push_back(new Rep(re_rep->getRE(), re_rep->getLB()-1, re_rep->getLB()-1));
    48             seq_lst->push_back(removeNullablePrefix(re_rep->getRE()));
    49 
    50             return RE_Simplifier::mkSeq(Seq::Normal, seq_lst);
     32        else if (hasNullablePrefix(re_rep->getRE())) {
     33            Vector seq;
     34            seq.push_back(removeNullablePrefix(re_rep->getRE()));
     35            seq.push_back(new Rep(re_rep->getRE(), re_rep->getLB() - 1, re_rep->getLB() - 1));
     36            re = RE_Simplifier::makeSeq(Seq::Normal, seq);
    5137        }
    52         else
    53         {
    54             return RE_Simplifier::mkRep(re_rep->getRE(), re_rep->getLB(), re_rep->getLB());
     38        else {
     39            re = RE_Simplifier::makeRep(re_rep->getRE(), re_rep->getLB(), re_rep->getLB());
    5540        }
    5641    }
    57     else
    58     {
    59         return re;
    60     }
     42    return re;
    6143}
    6244
    63 std::list<RE*>* RE_Nullable::removeNullableSeqPrefix(std::list<RE*>* re_list)
    64 {
    65     if (re_list->size() == 0)
    66     {
    67         return re_list;
     45
     46inline Seq * RE_Nullable::removeNullableSeqPrefix(const Seq * seq) {
     47    Seq * new_seq = new Seq(seq->getType());
     48    if (!seq->empty()) {
     49        auto i = seq->begin();
     50        // find the first non-nullable prefix
     51        while (i != seq->end() && isNullable(*i)) {
     52            ++i;
     53        }
     54        if (i == seq->end()) {
     55            return new_seq;
     56        }
     57        // push the first non-nullable seq item to the front of the new_seq
     58        new_seq->push_back(removeNullablePrefix(*i));
     59        std::copy(++i, seq->end(), std::back_inserter(*new_seq));
    6860    }
    69     else if(isNullable(re_list->front()))
    70     {
    71         re_list->pop_front();
    72 
    73         return removeNullableSeqPrefix(re_list);
    74     }
    75     else
    76     {
    77         RE* re = re_list->front();
    78         re_list->pop_front();
    79         re_list->push_front(removeNullablePrefix(re));
    80         re_list->reverse();
    81 
    82         return re_list;
    83     }
     61    return new_seq;
    8462}
    8563
    86 RE* RE_Nullable::removeNullableSuffix(RE* re)
    87 {
    88     if (Seq* re_seq = dynamic_cast<Seq*>(re))
    89     {
    90         std::list<RE*>* re_list = re_seq->GetREList();
    91         std::list<RE*>* t1_list = new std::list<RE*>();
    92         t1_list->assign(re_list->begin(), re_list->end());
    93         Seq* new_seq = new Seq(removeNullableSeqSuffix(t1_list));
    94         new_seq->setType(re_seq->getType());
    95         return new_seq;
     64RE * RE_Nullable::removeNullableSuffix(RE * re) {
     65    if (Seq * re_seq = dynamic_cast<Seq*>(re)) {
     66        re = removeNullableSeqSuffix(re_seq);
    9667    }
    97     else if (Alt* re_alt = dynamic_cast<Alt*>(re))
    98     {
     68    else if (Alt* re_alt = dynamic_cast<Alt*>(re)) {
    9969        Alt* new_alt = new Alt();
    100         std::list<RE*>::iterator it;
    101 
    102         for (it = re_alt->GetREList()->begin(); it != re_alt->GetREList()->end(); ++it)
    103         {
    104             new_alt->AddREListItem(removeNullableSuffix(*it));
     70        for (RE * re : *re_alt) {
     71            new_alt->push_back(removeNullableSuffix(re));
    10572        }
    106 
    107         return new_alt;
     73        re = new_alt;
    10874    }
    109     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    110     {
    111         if ((re_rep->getLB() == 0) || (isNullable(re_rep->getRE())))
    112         {
    113             //std::cout << "removeNullableSuffix->Rep->lb=0 or is nullable:" << std::endl;
    114             return new Seq();
     75    else if (Rep * re_rep = dynamic_cast<Rep*>(re)) {
     76        if ((re_rep->getLB() == 0) || (isNullable(re_rep->getRE()))) {
     77            re = new Seq();
    11578        }
    116         else if (hasNullableSuffix(re_rep->getRE()))
    117         {
    118             //std::cout << "removeNullableSuffix->Rep->hasNullableSuffix:" << std::endl;
    119             std::list<RE*>* seq_lst = new std::list<RE*>();
    120             seq_lst->push_back(removeNullableSuffix(re_rep->getRE()));
    121             seq_lst->push_back(new Rep(re_rep->getRE(), re_rep->getLB()-1, re_rep->getLB()-1));
    122 
    123             return RE_Simplifier::mkSeq(Seq::Normal, seq_lst);
     79        else if (hasNullableSuffix(re_rep->getRE())) {
     80            Vector seq;
     81            seq.push_back(new Rep(re_rep->getRE(), re_rep->getLB() - 1, re_rep->getLB() - 1));
     82            seq.push_back(removeNullableSuffix(re_rep->getRE()));
     83            re = RE_Simplifier::makeSeq(Seq::Normal, seq);
    12484        }
    125         else
    126         {
    127             return RE_Simplifier::mkRep(re_rep->getRE(), re_rep->getLB(), re_rep->getLB());
     85        else {
     86            re = RE_Simplifier::makeRep(re_rep->getRE(), re_rep->getLB(), re_rep->getLB());
    12887        }
    12988    }
    130     else
    131     {
    132         return re;
    133     }
     89    return re;
    13490}
    13591
    136 std::list<RE*>* RE_Nullable::removeNullableSeqSuffix(std::list<RE*>* re_list)
    137 {
    138     if (re_list->size() == 0)
    139     {
    140         return re_list;
     92inline Seq * RE_Nullable::removeNullableSeqSuffix(const Seq * seq) {
     93    Seq * new_seq = new Seq(seq->getType());
     94    if (!seq->empty()) {
     95        auto i = seq->end();
     96        // find the last non-nullable suffix
     97        while (i != seq->begin() && isNullable(*--i));
     98
     99        if (i != seq->begin()) {
     100            std::copy(seq->begin(), i, std::back_inserter(*new_seq));
     101            new_seq->push_back(removeNullableSuffix(*i));
     102        }
    141103    }
    142 
    143     RE* seq_re = re_list->front();
    144     re_list->pop_front();
    145 
    146     if (isNullableSeq(re_list))
    147     {
    148 
    149         std::list<RE*>* t1_list = new std::list<RE*>();
    150         t1_list->push_back(removeNullableSuffix(seq_re));
    151 
    152         return t1_list;
    153     }
    154 
    155     std::list<RE*>* t2_list;
    156     t2_list = removeNullableSeqSuffix(re_list);
    157     t2_list->push_back(seq_re);
    158 
    159     return t2_list;
     104    return new_seq;
    160105}
    161106
    162 bool RE_Nullable::isNullable(RE* re)
    163 {
    164     if (Seq* re_seq = dynamic_cast<Seq*>(re))
    165     {
    166         return isNullableSeq(re_seq->GetREList());
     107bool RE_Nullable::isNullable(const RE * re) {
     108    if (const Seq * re_seq = dynamic_cast<const Seq*>(re)) {
     109        return isNullableVector(re_seq);
    167110    }
    168     else if (Alt* re_alt = dynamic_cast<Alt*>(re))
    169     {
    170         return isNullableAlt(re_alt->GetREList());
     111    else if (const Alt* re_alt = dynamic_cast<const Alt*>(re)) {
     112        return isNullableVector(re_alt);
    171113    }
    172     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    173     {   
     114    else if (const Rep* re_rep = dynamic_cast<const Rep*>(re)) {
    174115        return re_rep->getLB() == 0 ? true : isNullable(re_rep->getRE());
    175116    }
    176     else {
    177         return false;
    178     }
     117    return false;
    179118}
    180119
    181 bool RE_Nullable::isNullableSeq(std::list<RE*>* re_list)
    182 {
    183     std::list<RE*>::iterator it = re_list->begin();
    184     return isNullableSeq_helper(re_list, it);
     120inline bool RE_Nullable::isNullableVector(const Vector * vec) {
     121    for (const RE * re : *vec) {
     122        if (!isNullable(re)) {
     123            return false;
     124        }
     125    }
     126    return true;
    185127}
    186128
    187 bool RE_Nullable::isNullableSeq_helper(std::list<RE*>* re_list, std::list<RE*>::iterator it)
    188 {
    189     if (it != re_list->end())
    190     {
    191         return isNullable(*it) ? isNullableSeq_helper(re_list, ++it) : false;
     129bool RE_Nullable::hasNullablePrefix(const RE * re) {
     130    bool nullable = false;
     131    if (const Seq * seq = dynamic_cast<const Seq*>(re)) {
     132        nullable = isNullable(seq->front()) ? true : hasNullablePrefix(seq->front());
    192133    }
    193     else
    194     {
    195         return true;
    196     }
    197 }
    198 
    199 bool RE_Nullable::isNullableAlt(std::list<RE*>* re_list)
    200 {
    201     std::list<RE*>::iterator it = re_list->begin();
    202     return isNullableAlt_helper(re_list, it);
    203 }
    204 
    205 bool RE_Nullable::isNullableAlt_helper(std::list<RE*>* re_list, std::list<RE*>::iterator it)
    206 {
    207     if (it != re_list->end())
    208     {
    209         return isNullable(*it) ? true : isNullableAlt_helper(re_list, ++it);
    210     }
    211     else
    212     {
    213         return false;
    214     }
    215 }
    216 
    217 bool RE_Nullable::hasNullablePrefix(RE* re)
    218 {
    219     if (Seq* seq = dynamic_cast<Seq*>(re))
    220     {
    221         if (isNullable(seq->GetREList()->back()))
    222         {
    223             return true;
    224         }
    225         else
    226         {
    227             return hasNullablePrefix(seq->GetREList()->back());
    228         }
    229     }
    230     else if (Alt* alt = dynamic_cast<Alt*>(re))
    231     {
    232         if (alt->GetREList()->size() == 0)
    233         {
    234             return false;
    235         }
    236         else
    237         {
    238             if (hasNullablePrefix(alt->GetREList()->back()))
    239             {
    240                 return true;
    241             }
    242             else
    243             {
    244                 std::list<RE*> alt_list;
    245                 std::list<RE*>::iterator it;
    246                 it = alt->GetREList()->end();
    247                 it--;
    248                 alt_list.insert(alt_list.end(), alt->GetREList()->begin(), it);
    249                 alt_list.reverse();
    250 
    251                 return hasNullablePrefix(new Alt(alt_list));
     134    else if (const Alt * alt = dynamic_cast<const Alt*>(re)) {
     135        if (!alt->empty()) {
     136            nullable = true;
     137            for (const RE * re : *alt) {
     138                if (!hasNullablePrefix(re)) {
     139                    nullable = false;
     140                    break;
     141                }
    252142            }
    253143        }
    254144    }
    255     else if (Rep* rep = dynamic_cast<Rep*>(re))
    256     {
    257         return hasNullablePrefix(rep->getRE());
     145    else if (const Rep * rep = dynamic_cast<const Rep*>(re)) {
     146        nullable = hasNullablePrefix(rep->getRE());
    258147    }
    259     else
    260     {
    261         return false;
    262     }
     148    return nullable;
    263149}
    264150
    265 bool RE_Nullable::hasNullableSuffix(RE* re)
    266 {
    267     if (Seq* seq = dynamic_cast<Seq*>(re))
    268     {
    269         if (seq->GetREList()->size() == 1)
    270         {
    271             if (isNullable(seq->GetREList()->back()))
    272             {
    273                 return true;
    274             }
    275             else
    276             {
    277                 return hasNullableSuffix(seq->GetREList()->front());
    278             }
    279         }
    280         else
    281         {
    282             std::list<RE*> seq_list;
    283             std::list<RE*>::iterator it;
    284             it = seq->GetREList()->begin();
    285             it++;
    286             seq_list.insert(seq_list.end(), it, seq->GetREList()->end());
    287             seq_list.reverse();
    288 
    289             return hasNullableSuffix(new Seq(seq_list));
    290         }
     151bool RE_Nullable::hasNullableSuffix(const RE * re) {
     152    bool nullable = false;
     153    if (const Seq * seq = dynamic_cast<const Seq*>(re)) {
     154        nullable = isNullable(seq->back()) ? true : hasNullablePrefix(seq->back());
    291155    }
    292     else if (Alt* alt = dynamic_cast<Alt*>(re))
    293     {
    294         if (alt->GetREList()->size() == 0)
    295         {
    296             return false;
    297         }
    298         else
    299         {
    300             if (hasNullableSuffix(alt->GetREList()->front()))
    301             {
    302                 return true;
    303             }
    304             else
    305             {
    306                 std::list<RE*> alt_list;
    307                 std::list<RE*>::iterator it;
    308                 it = alt->GetREList()->begin();
    309                 it++;
    310                 alt_list.insert(alt_list.begin(), it, alt->GetREList()->end());
    311                 alt_list.reverse();
    312 
    313                 return hasNullableSuffix(new Alt(alt_list));
     156    else if (const Alt * alt = dynamic_cast<const Alt*>(re)) {
     157        if (!alt->empty()) {
     158            nullable = true;
     159            for (const RE * re : *alt) {
     160                if (!hasNullableSuffix(re)) {
     161                    nullable = false;
     162                    break;
     163                }
    314164            }
    315165        }
    316166    }
    317     else if (Rep* rep = dynamic_cast<Rep*>(re))
    318     {
    319         return hasNullableSuffix(rep->getRE());
     167    else if (const Rep * rep = dynamic_cast<const Rep*>(re)) {
     168        nullable = hasNullableSuffix(rep->getRE());
    320169    }
    321     else
    322     {
    323         return false;
    324     }
     170    return nullable;
    325171}
    326172
  • icGREP/icgrep-devel/icgrep/re_nullable.h

    r3917 r4182  
    44//Regular Expressions
    55#include "re_re.h"
    6 #include "re_cc.h"
    7 #include "re_start.h"
    8 #include "re_end.h"
    96#include "re_seq.h"
    10 #include "re_alt.h"
    11 #include "re_rep.h"
    12 #include "re_simplifier.h"
     7#include <vector>
    138
    14 #include <list>
    15 
    16 class RE_Nullable
    17 {
     9class RE_Nullable {
     10    typedef RE::Vector Vector;
    1811public:
    1912    static RE* removeNullablePrefix(RE* re);
    2013    static RE* removeNullableSuffix(RE* re);
    2114private:
    22     static bool isNullable(RE* re);
    23     static bool isNullableSeq(std::list<RE*>* re_list);
    24     static bool isNullableSeq_helper(std::list<RE*>* re_list, std::list<RE*>::iterator it);
    25     static bool isNullableAlt(std::list<RE*>* re_list);
    26     static bool isNullableAlt_helper(std::list<RE*>* re_list, std::list<RE*>::iterator it);
    27     static bool hasNullablePrefix(RE* re);
    28     static bool hasNullableSuffix(RE* re);
    29     static std::list<RE*>* removeNullableSeqPrefix(std::list<RE*>* re_list);
    30     static std::list<RE*>* removeNullableSeqSuffix(std::list<RE*>* re_list);
     15    static bool isNullable(const RE * re);
     16    static bool isNullableVector(const Vector * vec);
     17    static bool hasNullablePrefix(const RE *re);
     18    static bool hasNullableSuffix(const RE * re);
     19    static Seq * removeNullableSeqPrefix(const Seq * seq);
     20    static Seq * removeNullableSeqSuffix(const Seq *seq);
    3121};
    3222
  • icGREP/icgrep-devel/icgrep/re_parser.cpp

    r4017 r4182  
    66
    77#include "re_parser.h"
    8 
    9 
    10 ParseResult* RE_Parser::parse_re(std::string input_string)
     8#include "re_alt.h"
     9#include "re_end.h"
     10#include "re_rep.h"
     11#include "re_seq.h"
     12#include "re_start.h"
     13#include "parsefailure.h"
     14#include <algorithm>
     15
     16RE * RE_Parser::parse_re(const std::string & regular_expression, const bool allow_escapes_within_charset) {
     17    RE_Parser parser(regular_expression, allow_escapes_within_charset);
     18    RE * re = parser.parse_alt(false);
     19    if (re == nullptr) {
     20        throw ParseFailure("An unexpected parsing error occurred!");
     21    }
     22    return re;
     23}
     24
     25inline RE_Parser::RE_Parser(const std::string & regular_expression, const bool allow_escapes_within_charset)
     26: _cursor(regular_expression.begin())
     27, _end(regular_expression.end())
     28, _allow_escapes_within_charset(allow_escapes_within_charset)
    1129{
    12     parse_result_retVal re_result = parse_re_helper(input_string);
    13 
    14     if (re_result.remaining.length() == 0)
     30
     31}
     32
     33RE * RE_Parser::parse_alt(const bool subexpression) {
     34    std::unique_ptr<Alt> alt(new Alt());
     35    for (;;) {
     36        alt->push_back(parse_seq());
     37        if (_cursor == _end || *_cursor != '|') {
     38            break;
     39        }
     40        ++_cursor; // advance past the alternation character '|'
     41    }
     42    if (alt->empty())
    1543    {
    16         return re_result.result;
    17     }
    18     else if (ParseSuccess* re_success = dynamic_cast<ParseSuccess*>(re_result.result))
     44        throw NoRegularExpressionFound();
     45    }
     46    else if (subexpression) {
     47        if (_cursor == _end || *_cursor != ')') {
     48            throw ParseFailure("Parenthesization error!");
     49        }
     50        ++_cursor;
     51    }
     52    else if (_cursor != _end) { // !subexpression
     53        throw ParseFailure("Cannot fully parse statement!");
     54    }
     55
     56    RE * re;
     57    if (alt->size() == 1) {
     58        re = alt->back();
     59        alt->pop_back();
     60    }
     61    else {
     62        re = alt.release();
     63    }
     64    return re;
     65}
     66
     67inline RE * RE_Parser::parse_seq() {
     68    std::unique_ptr<Seq> seq(new Seq());
     69    for (;;) {
     70        RE * re = parse_next_token();
     71        if (re == nullptr) {
     72            break;
     73        }
     74        seq->push_back(extend_item(re));
     75    }
     76    if (seq->empty())
    1977    {
    20         ParseFailure* failure = new ParseFailure("Junk remaining!");
    21 
    22         return failure;
    23     }
    24     else if (ParseFailure* re_failure = dynamic_cast<ParseFailure*>(re_result.result))
    25     {
    26         return re_failure;
    27     }
    28     else
    29     {
    30         return 0;
    31     }
    32 }
    33 
    34 parse_result_retVal RE_Parser::parse_re_helper(std::string s)
    35 {
    36     parse_result_retVal result_retVal;
    37 
    38     parse_re_list_retVal af_result = parse_re_alt_form_list(s);
    39 
    40     if (af_result.re_list.size() == 0)
    41     {
    42         result_retVal.result = new ParseFailure("No regular expression found!");
    43         result_retVal.remaining = s;
    44     }
    45     else if (af_result.re_list.size() == 1)
    46     {
    47         result_retVal.result = new ParseSuccess(af_result.re_list.front());
    48         result_retVal.remaining = af_result.remaining;
    49     }
    50     else
    51     {
    52         result_retVal.result = new ParseSuccess(new Alt(&af_result.re_list));
    53         result_retVal.remaining = af_result.remaining;
    54     }
    55 
    56     return result_retVal;
    57 }
    58 
    59 parse_re_list_retVal RE_Parser::parse_re_alt_form_list(std::string s)
    60 {
    61     parse_re_list_retVal re_list_retVal;
    62     parse_result_retVal form_result = parse_re_form(s);
    63 
    64     if (ParseSuccess* re_success = dynamic_cast<ParseSuccess*>(form_result.result))
    65     {
    66         if (form_result.remaining.operator [](0) == '|')
    67         {           
    68             parse_re_list_retVal t1_re_list_retVal =
    69                     parse_re_alt_form_list(form_result.remaining.substr(1, form_result.remaining.length() - 1));
    70             std::list<RE*>::iterator it;
    71             it=t1_re_list_retVal.re_list.begin();
    72             re_list_retVal.re_list.assign(it, t1_re_list_retVal.re_list.end());
    73             re_list_retVal.remaining = t1_re_list_retVal.remaining;
    74         }
    75         else
    76         {
    77             re_list_retVal.remaining = form_result.remaining;
    78         }
    79         re_list_retVal.re_list.push_back(re_success->getRE());
    80     }
    81     else
    82     {
    83         re_list_retVal.re_list.clear();
    84         re_list_retVal.remaining = s;
    85     }
    86 
    87     return re_list_retVal;
    88 }
    89 
    90 parse_result_retVal RE_Parser::parse_re_form(std::string s)
    91 {
    92     parse_result_retVal form_retVal;
    93     parse_re_list_retVal item_list_result = parse_re_item_list(s);
    94 
    95     if (item_list_result.re_list.size() == 0)
    96     {
    97         form_retVal.result = new ParseFailure("No Regular Expression Found!");
    98         form_retVal.remaining = s;
    99     }
    100     else if (item_list_result.re_list.size() == 1)
    101     {
    102         form_retVal.result = new ParseSuccess(item_list_result.re_list.front());
    103         form_retVal.remaining = item_list_result.remaining;
    104     }
    105     else
    106     {
    107         form_retVal.result = new ParseSuccess(new Seq(&item_list_result.re_list));
    108         form_retVal.remaining = item_list_result.remaining;
    109     }
    110 
    111     return form_retVal;
    112 }
    113 
    114 parse_re_list_retVal RE_Parser::parse_re_item_list(std::string s)
    115 {
    116     parse_re_list_retVal item_list_retVal;
    117     parse_result_retVal item_result = parse_re_item(s);
    118 
    119     if (ParseSuccess* re_success = dynamic_cast<ParseSuccess*>(item_result.result))
    120     {
    121         parse_re_list_retVal t1_item_list_retVal = parse_re_item_list(item_result.remaining);
    122 
    123         std::list<RE*>::iterator it;
    124         it=t1_item_list_retVal.re_list.begin();
    125         item_list_retVal.re_list.assign(it, t1_item_list_retVal.re_list.end());
    126         item_list_retVal.re_list.push_back(re_success->getRE());
    127         item_list_retVal.remaining = t1_item_list_retVal.remaining;
    128     }
    129     else
    130     {
    131         item_list_retVal.re_list.clear();
    132         item_list_retVal.remaining = s;
    133     }
    134 
    135     return item_list_retVal;
    136 }
    137 
    138 parse_result_retVal RE_Parser::parse_re_item(std::string s)
    139 {
    140     parse_result_retVal item_retVal;
    141     parse_result_retVal unit_result = parse_re_unit(s);
    142 
    143     if (ParseSuccess* re_success = dynamic_cast<ParseSuccess*>(unit_result.result))
    144     {
    145         item_retVal = extend_item(re_success->getRE(), unit_result.remaining);
    146     }
    147     else
    148     {
    149         item_retVal.result = new ParseFailure("Parse item failure!");
    150         item_retVal.remaining = s;
    151     }
    152 
    153     return item_retVal;
    154 }
    155 
    156 parse_result_retVal RE_Parser::parse_re_unit(std::string s)
    157 {
    158     parse_result_retVal unit_retVal;
    159 
    160     if (s.length() == 0)
    161     {
    162         unit_retVal.result = new ParseFailure("Incomplete regular expression! (parse_re_unit)");
    163         unit_retVal.remaining = "";
    164     }
    165     else if (s.operator[](0) == '(')
    166     {
    167         parse_result_retVal t1_unit_retVal = parse_re_helper(s.substr(1, s.length() - 1));
    168         ParseSuccess* success = dynamic_cast<ParseSuccess*>(t1_unit_retVal.result);
    169         if ((success != 0) && (t1_unit_retVal.remaining.operator[](0) == ')'))
    170         {
    171             unit_retVal.result = success;
    172             unit_retVal.remaining = t1_unit_retVal.remaining.substr(1, t1_unit_retVal.remaining.length() - 1);
    173         }
    174         else
    175         {
    176             unit_retVal.result = new ParseFailure("Bad parenthesized RE!");
    177             unit_retVal.remaining = s.substr(1, s.length() - 1);
    178         }
    179     }
    180     else if (s.operator [](0) == '^')
    181     {
    182         unit_retVal.result = new ParseSuccess(new Start);
    183         unit_retVal.remaining = s.substr(1, s.length() - 1);
    184     }
    185     else if (s.operator[](0) == '$')
    186     {
    187         unit_retVal.result = new ParseSuccess(new End);
    188         unit_retVal.remaining = s.substr(1, s.length() - 1);
    189     }
    190     else
    191     {
    192         unit_retVal = parse_cc(s);
    193     }
    194 
    195     return unit_retVal;
    196 }
    197 
    198 parse_result_retVal RE_Parser::extend_item(RE *re, std::string s)
    199 {
    200      parse_result_retVal extend_item_retVal;
    201 
    202      if (s.operator [](0) == '*')
    203      {
    204          return extend_item(new Rep(re, 0, unboundedRep), s.substr(1, s.length() - 1));
    205      }
    206      else if (s.operator[](0) == '?')
    207      {
    208          return extend_item(new Rep(re, 0, 1), s.substr(1, s.length() - 1));
    209      }
    210      else if (s.operator[](0) == '+')
    211      {
    212          return extend_item(new Rep(re, 1, unboundedRep), s.substr(1, s.length() - 1));
    213      }
    214      else if (s.operator[](0) == '{')
    215      {
    216         parse_int_retVal int_retVal = parse_int(s.substr(1, s.length() - 1));
    217 
    218         if ((int_retVal.i != -1) && (int_retVal.remaining.operator [](0) == '}'))
    219         {
    220             extend_item_retVal =
    221                     extend_item(new Rep(re, int_retVal.i, int_retVal.i), int_retVal.remaining.substr(1, int_retVal.remaining.length() - 1));
    222 
    223         }
    224         else if ((int_retVal.i != -1) && ((int_retVal.remaining.operator [](0) == ',') && (int_retVal.remaining.operator [](1) == '}')))
    225         {
    226             extend_item_retVal =
    227                     extend_item(new Rep(re, int_retVal.i, unboundedRep), int_retVal.remaining.substr(2, int_retVal.remaining.length() - 2));
    228 
    229         }
    230         else if ((int_retVal.i != -1) && (int_retVal.remaining.operator [](0) == ','))
    231         {
    232             parse_int_retVal t1_int_retVal = parse_int(int_retVal.remaining.substr(1, int_retVal.remaining.length() - 1));
    233 
    234             if ((t1_int_retVal.i != -1) && (t1_int_retVal.remaining.operator [](0) == '}'))
    235             {
    236                 extend_item_retVal =
    237                         extend_item(new Rep(re, int_retVal.i, t1_int_retVal.i), t1_int_retVal.remaining.substr(1, t1_int_retVal.remaining.length() - 1));
    238             }
    239             else
    240             {
    241                 extend_item_retVal.result = new ParseFailure("Bad upper bound!");
    242                 extend_item_retVal.remaining = int_retVal.remaining.substr(1, int_retVal.remaining.length() - 1);
    243             }
    244         }
    245         else
    246         {
    247             extend_item_retVal.result = new ParseFailure("Bad lower bound!");
    248             extend_item_retVal.remaining = s.substr(1, s.length() - 1);
    249         }
    250      }
    251      else
    252      {
    253          extend_item_retVal.result = new ParseSuccess(re);
    254          extend_item_retVal.remaining = s;
    255      }
    256 
    257      return extend_item_retVal;
    258 }
    259 
    260 parse_result_retVal RE_Parser::parse_cc(std::string s)
    261 {
    262     parse_result_retVal cc_retVal;
    263 
    264     if (s.operator [](0) == '\\')
    265     {
    266         if (s.operator [](1) == '?')
    267         {
    268             cc_retVal.result = new ParseSuccess(new CC('?'));
    269         }
    270         else if (s.operator [](1) == '+')
    271         {
    272             cc_retVal.result = new ParseSuccess(new CC('+'));
    273         }
    274         else if (s.operator [](1) == '*')
    275         {
    276             cc_retVal.result = new ParseSuccess(new CC('*'));
    277         }
    278         else if (s.operator [](1) == '(')
    279         {
    280             cc_retVal.result = new ParseSuccess(new CC('('));
    281         }
    282         else if (s.operator [](1) == ')')
    283         {
    284             cc_retVal.result = new ParseSuccess(new CC(')'));
    285         }
    286         else if (s.operator [](1) == '{')
    287         {
    288             cc_retVal.result = new ParseSuccess(new CC('{'));
    289         }
    290         else if (s.operator [](1) == '}')
    291         {
    292             cc_retVal.result = new ParseSuccess(new CC('}'));
    293         }
    294         else if (s.operator [](1) == '[')
    295         {
    296             cc_retVal.result = new ParseSuccess(new CC('['));
    297         }
    298         else if (s.operator [](1) == ']')
    299         {
    300             cc_retVal.result = new ParseSuccess(new CC(']'));
    301         }
    302         else if (s.operator [](1) == '|')
    303         {
    304             cc_retVal.result = new ParseSuccess(new CC('|'));
    305         }
    306         else if (s.operator [](1) == '.')
    307         {
    308             cc_retVal.result = new ParseSuccess(new CC('.'));
    309         }
    310         else if (s.operator [](1) == '\\')
    311         {
    312             cc_retVal.result = new ParseSuccess(new CC('\\'));
    313         }
    314         else if (s.operator [](1) == 'u')
    315         {
    316             parse_int_retVal hex_val = parse_hex(s.substr(2, s.length() - 2));
    317 
    318             if (hex_val.i == -1)
    319             {
    320                 cc_retVal.result = new ParseFailure("Bad Unicode hex notation!");
    321                 cc_retVal.remaining = hex_val.remaining;
    322             }
    323             else
    324             {
    325                 cc_retVal.result = new ParseSuccess(new CC(hex_val.i));
    326                 cc_retVal.remaining = hex_val.remaining;
    327             }
    328 
    329             return cc_retVal;
    330         }
    331         else if (s.operator [](1) == 'p')
    332         {
    333             return cc_retVal = parse_unicode_category(s.substr(2, s.length() - 2), /* negated = */ false);
    334         }
    335         else if (s.operator [](1) == 'P')
    336         {
    337             return cc_retVal = parse_unicode_category(s.substr(2, s.length() - 2), /* negated = */ true);
    338         }
    339         else
    340         {
    341             cc_retVal.result = new ParseFailure("Illegal backslash escape!");
    342             cc_retVal.remaining = s.substr(1, s.length() - 1);
    343 
    344             return cc_retVal;
    345         }
    346 
    347         cc_retVal.remaining = s.substr(2, s.length() - 2);
    348 
    349         return cc_retVal;
    350     }
    351 
    352     if (s.operator [](0) == '.')
    353     {       
    354         CC* cc = new CC();
    355         cc->insert_range(0, 9);
    356         cc->insert_range(11, 0x10FFFF);
    357         cc_retVal.result = new ParseSuccess(cc);
    358         cc_retVal.remaining = s.substr(1, s.length() - 1);
    359 
    360         return cc_retVal;
    361     }
    362 
    363     if (s.operator [](0) == '[')
    364     {
    365         if (s.operator[](1) == '^')
    366         {
    367             cc_retVal = negate_cc_result(parse_cc_body(s.substr(2, s.length() - 2)));
    368         }
    369         else
    370         {
    371             cc_retVal = parse_cc_body(s.substr(1, s.length() - 1));
    372         }
    373 
    374         return cc_retVal;
    375     }
    376 
    377     std::string metacharacters = "?+*(){}[]|";
    378     std::string c = s.substr(0,1);
    379 
    380     if (metacharacters.find(c) == std::string::npos)
    381     {
    382         cc_retVal.result = new ParseSuccess(new CC(s.operator [](0)));
    383         cc_retVal.remaining = s.substr(1, s.length() - 1);
    384     }
    385     else
    386     {
    387         cc_retVal.result = new ParseFailure("Metacharacter alone!");
    388         cc_retVal.remaining = s;
    389     }
    390 
    391     int next_byte = (s.operator [](0) & 0xFF);
    392 
    393     if ((next_byte >= 0xC0) && (next_byte <= 0xDF))
    394     {       
    395         cc_retVal = parse_utf8_bytes(1, s);
    396     }
    397     else if ((next_byte >= 0xE0) && (next_byte <= 0xEF))
    398     {
    399         cc_retVal = parse_utf8_bytes(2, s);
    400     }
    401     else if((next_byte >= 0xF0) && (next_byte <= 0xFF))
    402     {
    403         cc_retVal = parse_utf8_bytes(3, s);
    404     }
    405 
    406     return cc_retVal;
    407 }
    408 
    409 parse_result_retVal RE_Parser::parse_utf8_bytes(int suffix_count, std::string s)
    410 {
    411     CC* cc = new CC((s.operator [](0) & 0xFF));
    412     Seq* seq = new Seq();
    413     seq->setType(Seq::Byte);
    414     seq->AddREListItem(cc);
    415 
    416     return parse_utf8_suffix_byte(suffix_count, s.substr(1, s.length() - 1), seq);
    417 }
    418 
    419 parse_result_retVal RE_Parser::parse_utf8_suffix_byte(int suffix_byte_num, std::string s, Seq *seq_sofar)
    420 {
    421     parse_result_retVal result_RetVal;
    422 
    423     if (suffix_byte_num == 0)
    424     {
    425         result_RetVal.result = new ParseSuccess(seq_sofar);
    426         result_RetVal.remaining = s;
    427     }
    428     else if (s.length() == 0)
    429     {
    430         result_RetVal.result = new ParseFailure("Invalid UTF-8 encoding!");
    431         result_RetVal.remaining = "";
    432     }
    433     else
    434     {
    435         if ((s.operator [](0) & 0xC0) == 0x80)
    436         {
    437             CC* cc = new CC((s.operator [](0) & 0xFF));
    438             seq_sofar->AddREListItem(cc);
    439             suffix_byte_num--;
    440             result_RetVal = parse_utf8_suffix_byte(suffix_byte_num, s.substr(1, s.length() - 1), seq_sofar);
    441         }
    442         else
    443         {
    444             result_RetVal.result = new ParseFailure("Invalid UTF-8 encoding!");
    445             result_RetVal.remaining = s;
    446         }
    447     }
    448 
    449     return result_RetVal;
    450 }
    451 
    452 parse_result_retVal RE_Parser::parse_unicode_category(std::string s, bool negated)
    453 {
    454     parse_result_retVal result_retVal;
    455 
    456     if (s.operator [](0) == '{')
    457     {
    458         Name* name = new Name();
     78        throw NoRegularExpressionFound();
     79    }
     80
     81    RE * re;
     82    if (seq->size() == 1) {
     83        re = seq->back();
     84        seq->pop_back();
     85    }
     86    else {
     87        re = seq.release();
     88    }
     89    return re;
     90}
     91
     92RE * RE_Parser::parse_next_token() {
     93    RE * re = nullptr;
     94    if (_cursor != _end) {
     95        switch (*_cursor) {
     96            case '(':
     97                ++_cursor;
     98                re = parse_alt(true);
     99                break;
     100            case '^':
     101                ++_cursor;
     102                re = new Start;
     103                break;
     104            case '$':
     105                ++_cursor;
     106                re = new End;
     107                break;
     108            case '|': case ')':
     109                break;
     110            case '*': case '+': case '?': case ']': case '{': case '}':
     111                throw ParseFailure("Illegal metacharacter usage!");
     112            case '[':
     113                re = parse_charset();
     114                break;
     115            case '.': // the 'any' metacharacter
     116                re = parse_any_character();
     117                break;
     118            default:
     119                re = parse_literal();
     120                break;
     121        }
     122    }
     123    return re;
     124}
     125
     126CC * RE_Parser::parse_any_character() {
     127    CC * cc = new CC();
     128    cc->insert_range(0, 9);
     129    cc->insert_range(11, 0x10FFFF);
     130    ++_cursor;
     131    return cc;
     132}
     133
     134RE * RE_Parser::extend_item(RE * re) {
     135    if (_cursor == _end) {
     136        return re;
     137    }
     138    switch (*_cursor) {
     139        case '*':
     140            ++_cursor; // skip past the '*'
     141            re = new Rep(re, 0, UNBOUNDED_REP);
     142            break;
     143        case '?':
     144            ++_cursor; // skip past the '?'
     145            re = new Rep(re, 0, 1);
     146            break;
     147        case '+':
     148            ++_cursor; // skip past the '+'
     149            re = new Rep(re, 1, UNBOUNDED_REP);
     150            break;
     151        case '{':
     152            re = parse_range_bound(re);
     153            break;
     154        default:
     155            return re;
     156    }
     157    // this only occurs if we encountered one of the non-default cases above.
     158    return extend_item(re);
     159}
     160
     161inline RE * RE_Parser::parse_range_bound(RE * re) {
     162    ++_cursor;
     163    throw_incomplete_expression_error_if_end_of_stream();
     164    Rep * rep = nullptr;
     165    unsigned lower_bound;
     166    if (*_cursor == ',') {
     167        ++_cursor;
     168        lower_bound = 0;
     169    }
     170    else {
     171        lower_bound = parse_int();
     172    }
     173    throw_incomplete_expression_error_if_end_of_stream();
     174    if (*_cursor == '}') {
     175        rep = new Rep(re, lower_bound, lower_bound);
     176    }
     177    else if (*_cursor != ',') {
     178        throw BadLowerBound();
     179    }
     180    else { // [^,}]
     181        ++_cursor;
     182        throw_incomplete_expression_error_if_end_of_stream();
     183        if (*_cursor == '}') {
     184            rep = new Rep(re, lower_bound, UNBOUNDED_REP);
     185        }
     186        else {
     187            const unsigned upper_bound = parse_int();
     188            if (*_cursor != '}') {
     189                throw BadUpperBound();
     190            }
     191            rep = new Rep(re, lower_bound, upper_bound);
     192        }
     193    }
     194    ++_cursor;
     195    return rep;
     196}
     197
     198inline RE * RE_Parser::parse_literal() {
     199    // handle the escaped metacharacter (assuming it is one)
     200    if (*_cursor == '\\') {
     201        return parse_escaped_metacharacter();
     202    }
     203    else {
     204        return new CC(parse_utf8_codepoint());
     205    }
     206}
     207
     208inline RE * RE_Parser::parse_escaped_metacharacter() {
     209    ++_cursor;
     210    throw_incomplete_expression_error_if_end_of_stream();
     211    bool negated = false;
     212    switch (*_cursor) {
     213        case '(': case ')': case '*': case '+':
     214        case '.': case '?': case '[': case '\\':
     215        case ']': case '{': case '|': case '}':
     216            return new CC(*_cursor++);
     217        case 'u':
     218            return new CC(parse_hex());
     219        case 'P':
     220            negated = true;
     221        case 'p':
     222            return parse_unicode_category(negated);
     223    }
     224    throw ParseFailure("Illegal backslash escape!");
     225}
     226
     227unsigned RE_Parser::parse_utf8_codepoint() {
     228    unsigned c = static_cast<unsigned>(*_cursor++);
     229    if (c > 0x80) { // if non-ascii
     230        if (c < 0xC2) {
     231            throw InvalidUTF8Encoding();
     232        }
     233        else { // [0xC2, 0xFF]
     234            unsigned bytes = 0;
     235            if (c < 0xE0) { // [0xC2, 0xDF]
     236                c &= 0x1F;
     237                bytes = 1;
     238            }
     239            else if (c < 0xF0) { // [0xE0, 0xEF]
     240                c &= 0x0F;
     241                bytes = 2;
     242            }
     243            else { // [0xF0, 0xFF]
     244                c &= 0x0F;
     245                bytes = 3;
     246            }
     247            while (--bytes) {
     248                if (++_cursor == _end || (*_cursor & 0xC0) != 0x80) {
     249                    throw InvalidUTF8Encoding();
     250                }
     251                c = (c << 6) | static_cast<unsigned>(*_cursor & 0x3F);
     252            }
     253        }
     254    }
     255    return c;
     256}
     257
     258inline Name * RE_Parser::parse_unicode_category(const bool negated) {
     259    if (++_cursor != _end && *_cursor == '{') {
     260        std::unique_ptr<Name> name = std::unique_ptr<Name>(new Name);
    459261        name->setType(Name::UnicodeCategory);
    460262        name->setNegated(negated);
    461         result_retVal = parse_unicode_category1(s.substr(1,1), s.substr(2, s.length() - 2), name);
    462     }
    463     else
    464     {
    465         result_retVal.result = new ParseFailure("Incorrect Unicode character class format!");
    466         result_retVal.remaining = "";
    467     }
    468 
    469     return result_retVal;
    470 }
    471 
    472 parse_result_retVal RE_Parser::parse_unicode_category1(std::string character, std::string s, Name* name_sofar)
    473 {
    474     parse_result_retVal unicode_cat1_retVal;
    475 
    476     if (s.length() == 0)
    477     {
    478         delete name_sofar;
    479         unicode_cat1_retVal.result = new ParseFailure("Unclosed Unicode character class!");
    480         unicode_cat1_retVal.remaining = "";
    481     }
    482     else if (s.operator [](0) == '}')
    483     {
    484         name_sofar->setName(name_sofar->getName() + character);
    485         if (isValidUnicodeCategoryName(name_sofar))
    486         {
    487             unicode_cat1_retVal.result = new ParseSuccess(name_sofar);
    488             unicode_cat1_retVal.remaining = s.substr(1, s.length() - 1);
    489         }
    490         else
    491         {
    492             unicode_cat1_retVal.result = new ParseFailure("Unknown Unicode character class!");
    493             unicode_cat1_retVal.remaining = s.substr(1, s.length() - 1);
    494         }
    495     }
    496     else
    497     {
    498         name_sofar->setName(name_sofar->getName() + character);
    499         unicode_cat1_retVal = parse_unicode_category1(s.substr(0,1), s.substr(1, s.length() - 1), name_sofar);
    500     }
    501 
    502     return unicode_cat1_retVal;
    503 }
    504 
    505 parse_result_retVal RE_Parser::parse_cc_body(std::string s)
    506 {
    507     parse_result_retVal result_retVal;
    508 
    509     if (s.length() == 0)
    510     {
    511         result_retVal.result = new ParseFailure("Unclosed character class!");
    512         result_retVal.remaining = "";
    513     }
    514     else
    515     {
    516         CC* cc = new CC();
    517         result_retVal = parse_cc_body1(s.operator [](0), s.substr(1, s.length() - 1), cc);
    518     }
    519 
    520     return result_retVal;
    521 }
    522 
    523 parse_result_retVal RE_Parser::parse_cc_body0(std::string s, CC* cc_sofar)
    524 {
    525     parse_result_retVal cc_body0_retVal;
    526 
    527     if (s.length() == 0)
    528     {
    529         delete cc_sofar;
    530         cc_body0_retVal.result = new ParseFailure("Unclosed character class!");
    531         cc_body0_retVal.remaining = "";
    532     }
    533     else if (s.operator [](0) == ']')
    534     {
    535         cc_body0_retVal.result = new ParseSuccess(cc_sofar);
    536         cc_body0_retVal.remaining = s.substr(1, s.length() - 1);
    537     }
    538     else if ((s.operator [](0) == '-') && (s.operator [](1) == ']'))
    539     {
    540         cc_sofar->insert1('-');
    541         cc_body0_retVal.result = new ParseSuccess(cc_sofar);
    542         cc_body0_retVal.remaining = s.substr(2, s.length() - 2);
    543     }
    544     else if (s.operator [](0) == '-')
    545     {
    546         delete cc_sofar;
    547         cc_body0_retVal.result = new ParseFailure("Bad range in character class!");
    548         cc_body0_retVal.remaining = s.substr(1, s.length() - 1);
    549     }
    550     else
    551     {
    552         cc_body0_retVal = parse_cc_body1(s.operator [](0), s.substr(1, s.length() - 1), cc_sofar);
    553     }
    554 
    555     return cc_body0_retVal;
    556 }
    557 
    558 parse_result_retVal RE_Parser::parse_cc_body1(int chr, std::string s, CC* cc_sofar)
    559 {
    560     parse_result_retVal cc_body1_retVal;
    561 
    562     if (s.length() == 0)
    563     {
    564         delete cc_sofar;
    565         cc_body1_retVal.result = new ParseFailure("Unclosed character class!");
    566         cc_body1_retVal.remaining = "";
    567     }
    568     else if (s.operator [](0) == ']')
    569     {
    570         cc_sofar->insert1(chr);
    571         cc_body1_retVal.result = new ParseSuccess(cc_sofar);
    572         cc_body1_retVal.remaining = s.substr(1, s.length() - 1);
    573     }
    574     else if (s.length() == 1)
    575     {
    576         delete cc_sofar;
    577         cc_body1_retVal.result = new ParseFailure("Unclosed character class!");
    578         cc_body1_retVal.remaining = "";
    579     }
    580     else if ((s.operator [](0) == '-') && (s.operator [](1) == ']'))
    581     {
    582         cc_sofar->insert1(chr);
    583         cc_sofar->insert1('-');
    584         cc_body1_retVal = parse_cc_body0(s, cc_sofar);
    585     }
    586     else if ((s.operator [](0) == '-') && (s.operator [](1) == '\\') && (s.operator [](2) == 'u'))
    587     {
    588         parse_int_retVal int_retVal = parse_hex(s.substr(3, s.length() - 3));
    589 
    590         if (int_retVal.i == -1)
    591         {
    592             cc_body1_retVal.result = new ParseFailure("Bad Unicode hex notation!");
    593             cc_body1_retVal.remaining = "";
    594         }
    595         else
    596         {
    597             cc_sofar->insert_range(chr, int_retVal.i);
    598             cc_body1_retVal = parse_cc_body0(int_retVal.remaining, cc_sofar);
    599         }
    600     }
    601     else if ((s.operator [](0) == '-') && ( s.length() > 1))
    602     {
    603         cc_sofar->insert_range(chr, s.operator [](1));
    604         cc_body1_retVal = parse_cc_body0(s.substr(2, s.length() - 2), cc_sofar);
    605     }
    606     else if ((s.operator [](0) == 'u') && ( s.length() > 1))
    607     {
    608         parse_int_retVal int_retVal = parse_hex(s.substr(1, s.length() - 1));
    609 
    610         if (int_retVal.i == -1)
    611         {
    612             cc_body1_retVal.result = new ParseFailure("Bad Unicode hex notation!");
    613             cc_body1_retVal.remaining = "";
    614         }
    615         else
    616         {
    617             cc_body1_retVal = parse_cc_body1(int_retVal.i, int_retVal.remaining, cc_sofar);
    618         }
    619     }
    620     else
    621     {
    622         cc_sofar->insert1(chr);
    623         cc_body1_retVal = parse_cc_body1(s.operator [](0), s.substr(1, s.length() - 1), cc_sofar);
    624     }
    625 
    626     return cc_body1_retVal;
    627 }
    628 
    629 parse_int_retVal RE_Parser::parse_hex(std::string s)
    630 {
    631     parse_int_retVal int_retVal;
    632 
    633     if (s.operator [](0) == '{')
    634     {
    635         int hexval_sofar = 0;
    636         int_retVal = parse_hex_body(hexval_sofar, s.substr(1, s.length() - 1));
    637     }
    638     else
    639     {
    640         int_retVal.i = -1;
    641         int_retVal.remaining = s;
    642     }
    643 
    644     return int_retVal;
    645 }
    646 
    647 parse_int_retVal RE_Parser::parse_hex_body(int i, std::string s)
    648 {
    649     parse_int_retVal int_retVal;
    650 
    651     if (s.length() == 0)
    652     {
    653         int_retVal.i = i;
    654         int_retVal.remaining = "";
    655     }
    656     else if (s.operator [](0) == '}')
    657     {
    658         int_retVal.i = i;
    659         int_retVal.remaining = s.substr(1, s.length() - 1);
    660     }
    661     else if ((s.operator [](0) >= '0') && (s.operator [](0) <= '9'))
    662     {
    663         int_retVal = parse_hex_body(parse_hex_body1(i, s.substr(0,1)), s.substr(1, s.length() - 1));
    664     }
    665     else if ((s.operator [](0) >= 'a') && (s.operator [](0) <= 'f'))
    666     {
    667         int_retVal = parse_hex_body(parse_hex_body1(i, s.substr(0,1)), s.substr(1, s.length() - 1));
    668     }
    669     else if ((s.operator [](0) >= 'A') && (s.operator [](0) <= 'F'))
    670     {
    671         int_retVal = parse_hex_body(parse_hex_body1(i, s.substr(0,1)), s.substr(1, s.length() - 1));
    672     }
    673     else
    674     {
    675         int_retVal.i = -1;
    676         int_retVal.remaining = s;
    677     }
    678 
    679     return int_retVal;
    680 }
    681 
    682 int RE_Parser::parse_hex_body1(int i, std::string hex_str)
    683 {
    684     int retVal = 0;
    685     int newVal = 0;
    686 
    687     retVal = i << 4;
    688 
    689     std::stringstream ss(hex_str);
    690     ss >> std::hex >> newVal;
    691 
    692     retVal = retVal | newVal;
    693 
    694     return retVal;
    695 }
    696 
    697 parse_int_retVal RE_Parser::parse_int(std::string s)
    698 {
    699     parse_int_retVal int_retVal;
    700 
    701     if (isdigit(s.operator [](0)))
    702     {
    703         int_retVal = parse_int1(s.operator [](0) - 48, s.substr(1, s.length() - 1));
    704     }
    705     else
    706     {
    707         int_retVal.i = -1;
    708         int_retVal.remaining = s;
    709     }
    710 
    711     return int_retVal;
    712 }
    713 
    714 parse_int_retVal RE_Parser::parse_int1(int i, std::string s)
    715 {
    716     parse_int_retVal int1_retVal;
    717 
    718     if (s.length() == 0)
    719     {
    720         int1_retVal.i = i;
    721         int1_retVal.remaining = "";
    722     }
    723     else if (isdigit(s.operator [](0)))
    724     {
    725         int1_retVal = parse_int1(i * 10 + (s.operator [](0) - 48), s.substr(1, s.length() - 1));
    726     }
    727     else
    728     {
    729         int1_retVal.i = i;
    730         int1_retVal.remaining = s;
    731     }
    732 
    733     return int1_retVal;
    734 }
    735 
    736 parse_result_retVal RE_Parser::negate_cc_result(parse_result_retVal cc_result)
    737 {
    738     if (ParseSuccess* success = dynamic_cast<ParseSuccess*>(cc_result.result))
    739     {
    740         if (CC* cc = dynamic_cast<CC*>(success->getRE()))
    741         {
    742             cc->negate_class();
    743             //Remove any new-line.
    744             cc->remove1(10);
    745         }
    746     }
    747 
    748     return cc_result;
    749 }
    750 
    751 bool RE_Parser::isValidUnicodeCategoryName(Name* name)
    752 {
    753     std::string cat_name = name->getName();
    754 
    755     if (cat_name == "Cc")
     263        const cursor_t start = _cursor + 1;
     264        for (;;) {
     265            ++_cursor;
     266            if (_cursor == _end) {
     267                throw UnclosedUnicodeCharacterClass();
     268            }
     269            if (*_cursor == '}') {
     270                break;
     271            }
     272            ++_cursor;
     273        }
     274        name->setName(std::string(start, _cursor));
     275        if (isValidUnicodeCategoryName(name)) {
     276            ++_cursor;
     277            return name.release();
     278        }
     279    }
     280    throw ParseFailure("Incorrect Unicode character class format!");
     281}
     282
     283RE * RE_Parser::parse_charset() {
     284    std::unique_ptr<CC> cc(new CC());
     285    bool negated = false;
     286    bool included_closing_square_bracket = false;
     287    cursor_t start = ++_cursor;
     288    while (_cursor != _end) {
     289        bool literal = true;
     290        switch (*_cursor) {
     291            case '^':
     292                // If the first character after the [ is a ^ (caret) then the matching character class is complemented.
     293                if (start == _cursor) {
     294                    negated = true;
     295                    start = ++_cursor; // move the start ahead incase the next character is a [ or -
     296                    literal = false;                   
     297                }
     298                break;
     299            case ']':
     300                // To include a ], put it immediately after the opening [ or [^; if it occurs later it will
     301                // close the bracket expression.
     302                if (start == _cursor) {
     303                    cc->insert1(']');
     304                    ++_cursor;
     305                    included_closing_square_bracket = true;
     306                    literal = false;
     307                    break;
     308                }
     309                if (negated) {
     310                    negate_cc(cc);
     311                }
     312                ++_cursor;
     313                return cc.release();
     314            // The hyphen (-) is not treated as a range separator if it appears first or last, or as the
     315            // endpoint of a range.
     316            case '-':
     317                if (true) {
     318                    literal = false;
     319                    const cursor_t next = _cursor + 1;
     320                    if (next == _end) {
     321                        goto parse_failed;
     322                    }
     323                    if ((start == _cursor) ? (*next != '-') : (*next == ']')) {
     324                        _cursor = next;
     325                        cc->insert1('-');
     326                        break;
     327                    }
     328                }
     329                throw ParseFailure("Invalid Lower Range Bound!");
     330            // case ':':
     331        }
     332        if (literal) {
     333            unsigned low;
     334            if (parse_charset_literal(low)) {
     335                // the previous literal allows for a - to create a range; test for it
     336                if (_cursor == _end) {
     337                    break; // out of loop to failure handling
     338                }
     339                if (*_cursor == '-') { // in range unless the next character is a ']'
     340                    if (++_cursor == _end) {
     341                        break; // out of loop to failure handling
     342                    }
     343                    if (*_cursor != ']') {
     344                        unsigned high;
     345                        if (!parse_charset_literal(high)) {
     346                            throw ParseFailure("Invalid Upper Range Bound!");
     347                        }
     348                        cc->insert_range(low, high);
     349                    }
     350                    continue;
     351                }
     352            }
     353            cc->insert1(low);
     354        }
     355    }
     356parse_failed:
     357    if (included_closing_square_bracket) {
     358        throw ParseFailure("One ']' cannot close \"[]\" or \"[^]\"; use \"[]]\" or \"[^]]\" instead.");
     359    }
     360    else {
     361        throw UnclosedCharacterClass();
     362    }
     363}
     364
     365inline bool RE_Parser::parse_charset_literal(unsigned & literal) {
     366    if (_cursor == _end) {
     367        return false;
     368    }
     369    if (*_cursor == '\\') {
     370        if (++_cursor == _end) {
     371            return false;
     372        }
     373        switch (*_cursor) {
     374            case '(': case ')': case '*': case '+':
     375            case '.': case '?': case '[': case '\\':
     376            case ']': case '{': case '|': case '}':
     377                if (_allow_escapes_within_charset) {
     378                    literal = *_cursor++;
     379                    return true;
     380                }
     381                break;
     382            case 'u':
     383                literal = parse_hex();
     384                return true;
     385            // probably need to pass in the CC to handle \w, \s, etc...
     386        }
     387        throw ParseFailure("Unknown charset escape!");
     388    }
     389    else {
     390        literal = parse_utf8_codepoint();
    756391        return true;
    757     else if (cat_name == "Cf")
    758         return true;
    759     else if (cat_name == "Cn")
    760         return true;
    761     else if (cat_name == "Co")
    762         return true;
    763     else if (cat_name == "Cs")
    764         return true;
    765     else if (cat_name == "C")
    766         return true;
    767     else if (cat_name == "Ll")
    768         return true;
    769     else if (cat_name == "Lt")
    770         return true;
    771     else if (cat_name == "Lu")
    772         return true;
    773     else if (cat_name == "L&")
    774         return true;
    775     else if (cat_name == "Lc")
    776         return true;
    777     else if (cat_name == "Lm")
    778         return true;
    779     else if (cat_name == "Lo")
    780         return true;
    781     else if (cat_name == "L")
    782         return true;
    783     else if (cat_name == "Mc")
    784         return true;
    785     else if (cat_name == "Me")
    786         return true;
    787     else if (cat_name == "Mn")
    788         return true;
    789     else if (cat_name == "M")
    790         return true;
    791     else if (cat_name == "Nd")
    792         return true;
    793     else if (cat_name == "Nl")
    794         return true;
    795     else if (cat_name == "No")
    796         return true;
    797     else if (cat_name == "N")
    798         return true;
    799     else if (cat_name == "Pc")
    800         return true;
    801     else if (cat_name == "Pd")
    802         return true;
    803     else if (cat_name == "Pe")
    804         return true;
    805     else if (cat_name == "Pf")
    806         return true;
    807     else if (cat_name == "Pi")
    808         return true;
    809     else if (cat_name == "Po")
    810         return true;
    811     else if (cat_name == "Ps")
    812         return true;
    813     else if (cat_name == "P")
    814         return true;
    815     else if (cat_name == "Sc")
    816         return true;
    817     else if (cat_name == "Sk")
    818         return true;
    819     else if (cat_name == "Sm")
    820         return true;
    821     else if (cat_name == "So")
    822         return true;
    823     else if (cat_name == "S")
    824         return true;
    825     else if (cat_name == "Zl")
    826         return true;
    827     else if (cat_name == "Zp")
    828         return true;
    829     else if (cat_name == "Zs")
    830         return true;
    831     else if (cat_name == "Z")
    832         return true;
    833     else
    834         return false;
    835 }
    836 
    837 
    838 
    839 
    840 
    841 
    842 
    843 
    844 
    845 
    846 
    847 
    848 
    849 
    850 
    851 
    852 
    853 
    854 
    855 
    856 
     392    }
     393    return false;
     394}
     395
     396unsigned RE_Parser::parse_int() {
     397    unsigned value = 0;
     398    for (; _cursor != _end; ++_cursor) {
     399        if (!isdigit(*_cursor)) {
     400            break;
     401        }
     402        value *= 10;
     403        value += static_cast<int>(*_cursor) - 48;
     404    }
     405    return value;
     406}
     407
     408unsigned RE_Parser::parse_hex() {
     409    if (++_cursor != _end && *_cursor == '{') {
     410        unsigned value = 0;
     411        for (++_cursor; _cursor != _end; ++_cursor) {
     412            const char t = *_cursor;
     413            if (t == '}') {
     414                ++_cursor;
     415                return value;
     416            }
     417            value *= 16;
     418            if (t >= '0' && t <= '9') {
     419                value |= (t - '0');
     420            }
     421            else if ((t | 32) >= 'a' && (t | 32) <= 'f') {
     422                value |= ((t | 32) - 'a') + 10;
     423            }
     424            else {
     425                break;
     426            }
     427        }
     428    }
     429    throw ParseFailure("Bad Unicode hex notation!");
     430}
     431
     432inline void RE_Parser::negate_cc(std::unique_ptr<CC> & cc) {
     433    cc->negate_class();
     434    cc->remove1(10);
     435}
     436
     437bool RE_Parser::isValidUnicodeCategoryName(const std::unique_ptr<Name> & name) {
     438    static const char * SET_OF_VALID_CATEGORIES[] = {
     439        "C", "Cc", "Cf", "Cn", "Co", "Cs",
     440        "L", "L&", "Lc", "Ll", "Lm", "Lo", "Lt", "Lu",
     441        "M", "Mc", "Me", "Mn",
     442        "N", "Nd", "Nl", "No",
     443        "P", "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps",
     444        "S", "Sc", "Sk", "Sm", "So",
     445        "Z", "Zl", "Zp", "Zs"
     446    };
     447    // NOTE: this method isn't as friendly as using an unordered_set for VALID_CATEGORIES since it requires
     448    // that the set is in ALPHABETICAL ORDER; however it ought to have less memory overhead than an
     449    // unordered_set and roughly equivalent speed.
     450    return std::binary_search(std::begin(SET_OF_VALID_CATEGORIES), std::end(SET_OF_VALID_CATEGORIES), name->getName());
     451}
     452
     453inline void RE_Parser::throw_incomplete_expression_error_if_end_of_stream() const {
     454    if (_cursor == _end) throw IncompleteRegularExpression();
     455}
  • icGREP/icgrep-devel/icgrep/re_parser.h

    r4132 r4182  
    99
    1010#include "re_re.h"
    11 #include "re_alt.h"
    1211#include "re_cc.h"
    1312#include "re_name.h"
    14 #include "re_end.h"
    15 #include "re_rep.h"
    16 #include "re_seq.h"
    17 #include "re_start.h"
    18 #include "parseresult.h"
    19 #include "parsesuccess.h"
    20 #include "parsefailure.h"
    2113
    22 #include <fstream>
    23 #include <iostream>
    2414#include <string>
    25 #include <sstream>
    26 #include <vector>
    27 #include <ctype.h>
    28 
    29 
    30 struct parse_int_retVal{
    31     int i;
    32     std::string remaining;
    33 };
    34 
    35 struct parse_result_retVal{
    36     ParseResult* result;
    37     std::string remaining;
    38 };
    39 
    40 struct parse_re_list_retVal{
    41     std::list<RE*> re_list;
    42     std::string remaining;
    43 };
    44 
    45 struct parse_re_vector_retVal{
    46     std::vector<RE*> re_vector;
    47     std::string remaining;
    48 };
     15#include <list>
     16#include <memory>
    4917
    5018class RE_Parser
    5119{
    5220public:
    53     //RE_Parser();
    54     //The module exports the parse result.
    55     static ParseResult* parse_re(std::string intput_string);
     21
     22    static RE * parse_re(const std::string &intput_string, const bool allow_escapes_within_charset = false);
     23
    5624private:
    57     static parse_result_retVal parse_re_helper(std::string s);
    58     static parse_re_list_retVal parse_re_alt_form_list(std::string s);
    59     static parse_result_retVal parse_re_form(std::string s);
    60     static parse_re_list_retVal parse_re_item_list(std::string s);
    61     static parse_result_retVal parse_re_item(std::string s);
    62     static parse_result_retVal parse_re_unit(std::string s);
    63     static parse_result_retVal extend_item(RE* re, std::string s);
    64     static parse_result_retVal parse_cc(std::string s);
    65     static parse_result_retVal parse_cc_body(std::string s);
    66     static parse_result_retVal parse_cc_body0(std::string s, CC* cc_sofar);
    67     static parse_result_retVal parse_cc_body1(int chr, std::string s, CC* cc_sofar);
    68     static parse_result_retVal parse_utf8_bytes(int suffix_count, std::string s);
    69     static parse_result_retVal parse_utf8_suffix_byte(int suffix_byte_num, std::string s, Seq* seq_sofar);
    7025
    71     static parse_result_retVal parse_unicode_category(std::string s, bool negated);
    72     static parse_result_retVal parse_unicode_category1(std::string character, std::string s, Name* name_sofar);
    73     static bool isValidUnicodeCategoryName(Name* name);
     26    typedef std::string::const_iterator cursor_t;
    7427
    75     static parse_int_retVal parse_hex(std::string s);
    76     static parse_int_retVal parse_hex_body(int i, std::string s);
    77     static int parse_hex_body1(int i, std::string hex_str);
     28    RE_Parser(const std::string & regular_expression, const bool allow_escapes_within_charset);
    7829
    79     static parse_int_retVal parse_int(std::string s);
    80     static parse_int_retVal parse_int1(int i, std::string s);
    81     static parse_result_retVal negate_cc_result(parse_result_retVal cc_result);
     30    RE * parse_alt(const bool subexpression);
     31
     32    RE * parse_seq();
     33
     34    RE * parse_next_token();
     35
     36    CC * parse_any_character();
     37
     38    RE * extend_item(RE * re);
     39
     40    RE * parse_range_bound(RE * re);
     41
     42    RE * parse_literal();
     43
     44    RE * parse_escaped_metacharacter();
     45
     46    unsigned parse_utf8_codepoint();
     47
     48    Name * parse_unicode_category(const bool negated);
     49
     50    RE * parse_charset();
     51
     52    bool parse_charset_literal(unsigned & literal);
     53
     54    static bool isValidUnicodeCategoryName(const std::unique_ptr<Name> &name);
     55
     56    unsigned parse_hex();
     57
     58    unsigned parse_int();
     59
     60    static void negate_cc(std::unique_ptr<CC> & cc);
     61
     62    inline void throw_incomplete_expression_error_if_end_of_stream() const;
     63
     64private:
     65
     66    cursor_t                    _cursor;
     67    const cursor_t              _end;
     68    const bool                  _allow_escapes_within_charset;
    8269};
    8370
  • icGREP/icgrep-devel/icgrep/re_re.h

    r3850 r4182  
    88#define RE_H
    99
     10#include <vector>
     11
    1012class RE
    1113{
    1214public:
     15    typedef std::vector<RE*>            Vector;
    1316    virtual ~RE();
    1417protected:
  • icGREP/icgrep-devel/icgrep/re_reducer.cpp

    r3998 r4182  
    22
    33
    4 RE* RE_Reducer::reduce(RE* re, std::map<std::string, RE*>& re_map)
    5 {
    6     RE* retVal = 0;
    7 
    8     if (Alt* re_alt = dynamic_cast<Alt*>(re))
    9     {
    10         std::list<RE*> re_list;
    11         std::list<RE*>::reverse_iterator rit = re_alt->GetREList()->rbegin();
    12 
    13         for (rit = re_alt->GetREList()->rbegin(); rit != re_alt->GetREList()->rend(); ++rit)
    14         {
    15             re_list.push_back(reduce(*rit, re_map));
     4RE* RE_Reducer::reduce(RE* re, std::map<std::string, RE*>& re_map) {
     5    RE* retVal = nullptr;
     6    if (Alt* re_alt = dynamic_cast<Alt*>(re)) {
     7        Alt * new_alt = new Alt();
     8        for (RE * re : *re_alt) {
     9            new_alt->push_back(reduce(re, re_map));
    1610        }
    17 
    18         retVal = new Alt(&re_list);
     11        retVal = new_alt;
    1912    }
    20     else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    21     {
    22 
    23         if (re_seq->getType() == Seq::Byte)
    24         {
     13    else if (Seq* re_seq = dynamic_cast<Seq*>(re)) {
     14        Seq * new_seq = new Seq();
     15        for (RE * re : *re_seq) {
     16            new_seq->push_back(reduce(re, re_map));
     17        }
     18        if (re_seq->getType() == Seq::Byte) {
    2519            //If this is a sequence of byte classes then this is a multibyte sequence for a Unicode character class.
    26             std::list<RE*> re_list;
    27             std::list<RE*>::iterator it;
    28 
    29             for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
    30             {
    31                 re_list.push_front(reduce(*it, re_map));
    32             }
    33 
    34             Seq* new_seq =  new Seq(&re_list);
    3520            new_seq->setType(Seq::Byte);
    3621            std::string seqname = new_seq->getName();
     
    4025            retVal = name;
    4126        }
    42         else
    43         {
    44             std::list<RE*> re_list;
    45             std::list<RE*>::iterator it;
    46 
    47             for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
    48             {
    49                 re_list.push_front(reduce(*it, re_map));
    50             }
    51 
    52             retVal = new Seq(&re_list);
     27        else {
     28            retVal = new_seq;
    5329        }
    5430    }
    55     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    56     {
     31    else if (Rep* re_rep = dynamic_cast<Rep*>(re)) {
    5732        retVal = new Rep(reduce(re_rep->getRE(), re_map), re_rep->getLB(), re_rep->getUB());
    5833    }
    59     else if (CC* re_cc = dynamic_cast<CC*>(re))
    60     {
     34    else if (CC* re_cc = dynamic_cast<CC*>(re)) {
    6135        std::string ccname = re_cc->getName();
    6236        //If the character class isn't in the map then add it.
     
    6539        retVal = new Name(ccname);
    6640    }
    67     else if (Name* re_name = dynamic_cast<Name*>(re))
    68     {
     41    else if (Name* re_name = dynamic_cast<Name*>(re)) {
    6942        Name* name = new Name(re_name->getName());
    7043        name->setType(re_name->getType());
     
    7245        retVal = name;
    7346    }
    74     else if (Start* re_start = dynamic_cast<Start*>(re))
    75     {
     47    else if (dynamic_cast<Start*>(re)) {
    7648        retVal = new Start();
    7749    }
    78     else if (End* re_end = dynamic_cast<End*>(re))
    79     {
     50    else if (dynamic_cast<End*>(re)) {
    8051        retVal = new End();
    8152    }
    82 
    8353    return retVal;
    8454}
  • icGREP/icgrep-devel/icgrep/re_rep.cpp

    r3914 r4182  
    1919}
    2020
    21 RE* Rep::getRE()
     21RE* Rep::getRE() const
    2222{
    2323    return mRE;
    2424}
    2525
    26 int Rep::getLB()
     26int Rep::getLB() const
    2727{
    2828    return mLB;
     
    3434}
    3535
    36 int Rep::getUB()
     36int Rep::getUB() const
    3737{
    3838    return mUB;
  • icGREP/icgrep-devel/icgrep/re_rep.h

    r3914 r4182  
    1010#include "re_re.h"
    1111
    12 const int unboundedRep = -1;
     12const int UNBOUNDED_REP = -1;
    1313
    1414class Rep : public RE
     
    1717    Rep(RE* re, int lb, int ub);
    1818    ~Rep();
    19     RE* getRE();
    20     int getLB();
     19    RE* getRE() const;
     20    int getLB() const;
    2121    void setLB(int lb);
    22     int getUB();
     22    int getUB() const;
    2323    void setUB(int ub);
    2424private:
  • icGREP/icgrep-devel/icgrep/re_seq.cpp

    r3955 r4182  
    77#include "re_seq.h"
    88
     9
    910Seq::Seq()
     11: mType(Seq::Normal)
    1012{
    11     mList = new std::list<RE*>();
    12     mType = Seq::Normal;
     13
    1314}
    1415
    15 Seq::Seq(std::list<RE*>* lst)
     16Seq::Seq(const Type type)
     17: mType(type)
    1618{
    17     mList = new std::list<RE*>();
    18     std::list<RE*>::iterator it;
    19     it=lst->begin();
    20     mList->assign(it, lst->end());
    21     mList->reverse();
    22     mType = Seq::Normal;
     19
    2320}
    2421
    25 Seq::Seq(std::list<RE*> lst)
     22Seq::Seq(const Type type, iterator begin, iterator end)
     23: std::vector<RE*>(begin, end)
     24, mType(type)
    2625{
    27     mList = new std::list<RE*>();
    28     std::list<RE*>::iterator it;
    29     it=lst.begin();
    30     mList->assign(it, lst.end());
    31     mList->reverse();
    32     mType = Seq::Normal;
     26
    3327}
    3428
    35 Seq::~Seq()
    36 {
    37     while(!mList->empty()) delete mList->back(), mList->pop_back();
    38     delete mList;
     29Seq::~Seq() {
     30    for (RE * re : *this) {
     31        delete re;
     32    }
    3933}
    4034
    41 std::string Seq::getName()
    42 {
    43     if (mType == Seq::Byte)
    44     {
     35std::string Seq::getName() const {
     36    if (mType == Seq::Byte) {
    4537        std::string name = "Seq";
    46 
    47         std::list<RE*> re_list;
    48         std::list<RE*>::iterator it = mList->begin();
    49 
    50         for (it = mList->begin(); it != mList->end(); ++it)
    51         {
    52             if (CC* seq_cc = dynamic_cast<CC*>(*it))
    53             {
     38        for (RE * re : *this) {
     39            if (CC* seq_cc = dynamic_cast<CC*>(re)) {
    5440                name += seq_cc->getName();
    5541            }
    56             else if (Name* seq_name = dynamic_cast<Name*>(*it))
    57             {
     42            else if (Name* seq_name = dynamic_cast<Name*>(re)) {
    5843                name += seq_name->getName();
    5944            }
    60             else
    61             {
     45            else {
    6246                return "Bad Byte Sequence!";
    6347            }
    6448        }
    65 
    6649        return name;
    6750    }
    68     else
    69     {
     51    else {
    7052        return "Unnamed Sequence";
    7153    }
    7254}
    7355
    74 std::list<RE*>* Seq::GetREList()
    75 {
    76     return mList;
    77 }
    78 
    79 void Seq::AddREListItem(RE *re)
    80 {
    81     mList->push_back(re);
    82 }
    83 
    84 Seq::Type Seq::getType()
    85 {
     56Seq::Type Seq::getType() const {
    8657    return mType;
    8758}
    8859
    89 void Seq::setType(Seq::Type type)
    90 {
     60void Seq::setType(Seq::Type type) {
    9161    mType = type;
    9262}
  • icGREP/icgrep-devel/icgrep/re_seq.h

    r3955 r4182  
    1515#include <utility>
    1616
    17 class Seq : public RE
    18 {
     17class Seq : public RE, public RE::Vector {
    1918public:
    20     typedef enum {Normal,Byte} Type;
     19    typedef RE::Vector Vector;
     20    typedef enum {
     21        Normal,
     22        Byte
     23    } Type;
    2124    Seq();
    22     Seq(std::list<RE*>* lst);
    23     Seq(std::list<RE*> lst);
    24     ~Seq();
    25     std::list<RE*>* GetREList();
    26     void AddREListItem(RE *re);
    27     std::string getName();
    28     Type getType();
     25    Seq(const Type type);
     26    Seq(const Type type, iterator begin, iterator end);
     27    virtual ~Seq();
     28    std::string getName() const;
     29    Type getType() const;
    2930    void setType(Type type);
    3031private:
    31     std::list<RE*>* mList;
    32     Type mType;
     32    Type    mType;
    3333};
    3434
  • icGREP/icgrep-devel/icgrep/re_simplifier.cpp

    r3998 r4182  
    11#include "re_simplifier.h"
     2#include "re_cc.h"
     3#include "re_name.h"
     4#include "re_start.h"
     5#include "re_end.h"
     6#include "re_seq.h"
     7#include "re_alt.h"
     8#include "re_rep.h"
     9#include <algorithm>
     10#include <memory>
     11#include <queue>
    212
    3 RE* RE_Simplifier::simplify(RE* re)
    4 {
    5     RE* retVal = 0;
    6 
    7     if (Alt* re_alt = dynamic_cast<Alt*>(re))
    8     {
    9         std::list<RE*> re_list;
    10         std::list<RE*>::reverse_iterator rit = re_alt->GetREList()->rbegin();
    11 
    12         for (rit = re_alt->GetREList()->rbegin(); rit != re_alt->GetREList()->rend(); ++rit)
     13RE* RE_Simplifier::simplify(RE * re) {
     14    RE * retVal = re;
     15    if (Alt * re_alt = dynamic_cast<Alt*>(re)) {
     16        Vector simplified_alt;
     17        for (RE * re : *re_alt)
    1318        {
    14             re_list.push_back(simplify(*rit));
     19            simplified_alt.push_back(simplify(re));
    1520        }
    16 
    17         retVal = mkAlt(&re_list);
     21        retVal = makeAlt(simplified_alt);
    1822    }
    19     else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    20     {
    21         std::list<RE*> re_list;
    22         std::list<RE*>::iterator it;
    23 
    24         for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
     23    else if (Seq * re_seq = dynamic_cast<Seq*>(re)) {
     24        Vector simplified_seq;
     25        for (RE * re : *re_seq)
    2526        {
    26             re_list.push_front(simplify(*it));
     27            simplified_seq.push_back(simplify(re));
    2728        }
    28 
    29         retVal = mkSeq(re_seq->getType(), &re_list);
     29        retVal = makeSeq(re_seq->getType(), simplified_seq);
    3030    }
    31     else if (CC* re_cc = dynamic_cast<CC*>(re))
    32     {
     31    else if (CC* re_cc = dynamic_cast<CC*>(re)) {
    3332        retVal = re_cc;
    3433    }
    35     else if (Name* re_name = dynamic_cast<Name*>(re))
    36     {
     34    else if (Name* re_name = dynamic_cast<Name*>(re)) {
    3735        Name* name = new Name(re_name->getName());
    3836        name->setType(re_name->getType());
     
    4038        retVal = name;
    4139    }
    42     else if (Rep* re_rep = dynamic_cast<Rep*>(re))
    43     {
    44         retVal = mkRep(simplify(re_rep->getRE()), re_rep->getLB(), re_rep->getUB());
     40    else if (Rep* re_rep = dynamic_cast<Rep*>(re)) {
     41        retVal = makeRep(simplify(re_rep->getRE()), re_rep->getLB(), re_rep->getUB());
    4542    }
    46     else if (Start* re_start = dynamic_cast<Start*>(re))
    47     {
     43    else if (dynamic_cast<Start*>(re)) {
    4844        retVal = new Start();
    4945    }
    50     else if (End* re_end = dynamic_cast<End*>(re))
    51     {
     46    else if (dynamic_cast<End*>(re)) {
    5247        retVal = new End();
    5348    }
    54 
    5549    return retVal;
    5650}
    5751
    58 RE* RE_Simplifier::mkSeq(Seq::Type type, std::list<RE*>* re_list)
    59 {
     52RE * RE_Simplifier::makeSeq(const Seq::Type type, Vector & list) {
    6053    /*
    6154      mkSeq - make a sequence, but flatten.  Result might not be a Seq. If
     
    6356    */
    6457
    65     //We don't want to modify the AST that we are walking so we'll make a copy.
    66     std::list<RE*>* t1_list = new std::list<RE*>();
    67     //Linear in initial and final sizes.
    68     t1_list->assign(re_list->begin(), re_list->end());
    69     if (t1_list->size() > 0)
    70     { 
    71         std::list<RE*>* t2_list = mkSeqList(t1_list);
    72         if (t2_list->size() > 1)
    73         {
    74             Seq* new_seq = new Seq(t2_list);
    75             new_seq->setType(type);
    76             return new_seq;
     58    RE * re = nullptr;
     59    if (!list.empty()) {
     60        std::unique_ptr<Seq> seq = std::unique_ptr<Seq>(new Seq(type));
     61        // Reverse the order of the input list so we can more efficiently "pull" the first
     62        // character from the end. Note: this ought to be an inplace reversal.
     63        std::reverse(list.begin(), list.end());
     64
     65        while (!list.empty()) {
     66            RE * next = list.back();
     67            list.pop_back();
     68            if (Seq * re_seq = dynamic_cast<Seq*>(next)) {
     69                if (re_seq->getType() != Seq::Byte) {
     70                    // like above, insert the "subsequence" in reverse order
     71                    list.reserve(re_seq->size());
     72                    std::reverse_copy(re_seq->begin(), re_seq->end(), std::back_inserter(list));
     73                    continue;
     74                }
     75            }
     76            seq->push_back(next);
    7777        }
    78         else
    79         {
    80             return t2_list->back();
     78        if (seq->size() == 1) {
     79            re = seq->back();
     80            seq->pop_back();
     81        }
     82        else {
     83            re = seq.release();
    8184        }
    8285    }
    83     else
    84     {
    85         return 0;
    86     }
     86    return re;
    8787}
    8888
    89 std::list<RE*>* RE_Simplifier::mkSeqList(std::list<RE*>* re_list)
    90 {
    91     std::list<RE*>* ret_list = new std::list<RE*>();
    92     return mkSeqList_helper(ret_list, re_list);
    93 }
     89RE * RE_Simplifier::makeAlt(Vector & list) {
    9490
    95 std::list<RE*>* RE_Simplifier::mkSeqList_helper(std::list<RE*>* ret_list, std::list<RE*>* re_list)
    96 {
    97     /*
    98       Build a list for Seq, flattening subsequences.
    99     */
    100 
    101     if (re_list->size() == 0)
    102     {
    103         return ret_list;
    104     }
    105     else if (Seq* seq = dynamic_cast<Seq*>(re_list->back()))
    106     {
    107         if (seq->getType() == Seq::Byte)
    108         {
    109             ret_list->push_front(re_list->back());
    110             re_list->pop_back();
    111             return mkSeqList_helper(ret_list, re_list);
    112         }
    113         else
    114         {
    115             re_list->pop_back();
    116             seq->GetREList()->reverse();
    117             re_list->insert(re_list->end(), seq->GetREList()->begin(), seq->GetREList()->end());
    118 
    119             return mkSeqList_helper(ret_list, re_list);
    120         }
    121     }
    122     else
    123     {
    124         ret_list->push_front(re_list->back());
    125         re_list->pop_back();
    126         return mkSeqList_helper(ret_list, re_list);
    127     }
    128 }
    129 
    130 RE* RE_Simplifier::mkAlt(std::list<RE*>* re_list)
    131 {
    132     /*
    133       mkAlt - make a list of alternatives, but flatten, and combine character
    134       classes.  If there is only one alternative, simply return that.
    135     */
    136 
    137     std::list<RE*>* t1_list = new std::list<RE*>();
    138     t1_list->assign(re_list->begin(), re_list->end());
    139     if (t1_list->size() > 0)
    140     {
    141         std::list<RE*>* t2_list = mkAltList(t1_list);
    142         if (t2_list->size() > 1)
    143         {
    144             return new Alt(t2_list);
    145         }
    146         else
    147         {
    148             return t2_list->back();
    149         }
    150     }
    151     else
    152     {
    153         return 0;
    154     }
    155 }
    156 
    157 std::list<RE*>* RE_Simplifier::mkAltList(std::list<RE*>* re_list)
    158 {
    159     std::list<RE*>* ret_list = new std::list<RE*>();
    160     return mkAltList_helper(ret_list, re_list);
    161 }
    162 
    163 std::list<RE*>* RE_Simplifier::mkAltList_helper(std::list<RE*>* ret_list, std::list<RE*>* re_list)
    164 {
    16591    /*
    16692      Build a list for Alt, flattening alternative subgroups, and combining character classes.  We
     
    16894    */
    16995
    170     if (re_list->size() == 0)
    171     {
    172         return ret_list;
    173     }
    174     else if (Alt* alt = dynamic_cast<Alt*>(re_list->back()))
    175     {
    176         re_list->pop_back();
    177         re_list->insert(re_list->end(), alt->GetREList()->begin(), alt->GetREList()->end());
    178         return mkAltList_helper(ret_list, re_list);
    179     }
    180     else if (re_list->size() >= 2)
    181     {
    182         std::list<RE*>::iterator it;
    183         it = re_list->end();
    184         it--;
    185         if (CC* cc1 = dynamic_cast<CC*>(*it))
    186         {
    187             it--;
    188             if(CC* cc2 = dynamic_cast<CC*>(*it))
    189             {
    190                 CC* cc = new CC(cc1, cc2);
    191                 re_list->pop_back();
    192                 re_list->pop_back();
    193                 re_list->push_back(cc);
    194                 return mkAltList_helper(ret_list, re_list);
     96    RE * re = nullptr;
     97    if (!list.empty()) {
     98
     99        std::unique_ptr<Alt> new_alt = std::unique_ptr<Alt>(new Alt());
     100        std::queue<CC*> ccs;
     101
     102        while (!list.empty()) {
     103            RE * next = list.back();
     104            list.pop_back();
     105            if (Alt * re_alt = dynamic_cast<Alt*>(next)) {
     106                list.insert(list.end(), re_alt->begin(), re_alt->end());
    195107            }
    196             else
    197             {
    198                 std::list<RE*>::iterator item1 = re_list->end();
    199                 --item1;
    200                 std::list<RE*>::iterator item2 = item1;
    201                 --item2;
    202                 std::swap(*item1, *item2);
    203                 return mkAltList_helper(ret_list, re_list);
     108            else if (CC * cc = dynamic_cast<CC*>(next)) {
     109                ccs.push(cc);
     110            }
     111            else {
     112                new_alt->push_back(next);
    204113            }
    205114        }
    206         ret_list->push_front(re_list->back());
    207         re_list->pop_back();
    208         return mkAltList_helper(ret_list, re_list);
     115
     116        if (!ccs.empty()) {
     117            while (ccs.size() > 1) {
     118                CC * a = ccs.front(); ccs.pop();
     119                CC * b = ccs.front(); ccs.pop();
     120                ccs.push(new CC(a, b));
     121            }
     122            new_alt->push_back(ccs.front());
     123        }
     124
     125        if (new_alt->size() == 1) {
     126            re = new_alt->back();
     127            new_alt->pop_back();
     128        }
     129        else {
     130            re = new_alt.release();
     131        }
    209132    }
    210     else
    211     {
    212         ret_list->push_front(re_list->back());
    213         re_list->pop_back();
    214         return mkAltList_helper(ret_list, re_list);
     133
     134    return re;
     135}
     136
     137RE * RE_Simplifier::makeRep(RE * re, const int lb2, const int ub2)
     138{
     139    if (Rep* rep = dynamic_cast<Rep*>(re)) {
     140        if (((rep->getUB() == UNBOUNDED_REP) && (lb2 > 0)) ||
     141                ((rep->getUB() == UNBOUNDED_REP) && (rep->getLB() <= 1))) {
     142            return new Rep(rep->getRE(), rep->getLB() * lb2, UNBOUNDED_REP);
     143        }
     144        else if ((rep->getUB() == UNBOUNDED_REP) && (lb2 == 0)) {
     145            return new Rep(rep, 0, 1);
     146        }
     147        else if ((rep->getUB() * lb2) >= (rep->getLB() * (lb2 + 1) - 1)) {
     148            return new Rep(rep->getRE(), rep->getLB() * lb2, ubCombine(rep->getUB(), ub2));
     149        }
     150        else {
     151            return new Rep(rep, lb2, ub2);
     152        }
     153    }
     154    else {
     155        if (Seq* seq = dynamic_cast<Seq*>(re)) {
     156            if (seq->empty()) {
     157                return seq;
     158            }
     159        }
     160
     161        if ((lb2 == 0) && (ub2 == 0)) {
     162            return new Seq();
     163        }
     164        else if ((lb2 == 1) && (ub2 == 1)) {
     165            return re;
     166        }
     167        else {
     168            return new Rep(re, lb2, ub2);
     169        }
    215170    }
    216171}
    217172
    218 int RE_Simplifier::ubCombine(int h1, int h2)
     173inline int RE_Simplifier::ubCombine(const int h1, const int h2)
    219174{
    220     if ((h1 == unboundedRep) || (h2 == unboundedRep))
     175    if ((h1 == UNBOUNDED_REP) || (h2 == UNBOUNDED_REP))
    221176    {
    222         return unboundedRep;
     177        return UNBOUNDED_REP;
    223178    }
    224179    else
     
    227182    }
    228183}
    229 
    230 RE* RE_Simplifier::mkRep(RE* re, int lb2, int ub2)
    231 {
    232     if (Rep* rep = dynamic_cast<Rep*>(re))
    233     {
    234         if (((rep->getUB() == unboundedRep) && (lb2 > 0)) ||
    235                 ((rep->getUB() == unboundedRep) && (rep->getLB() <= 1)))
    236         {
    237             return new Rep(rep->getRE(), rep->getLB() * lb2, unboundedRep);
    238         }
    239         else if ((rep->getUB() == unboundedRep) && (lb2 == 0))
    240         {
    241             return new Rep(rep, 0, 1);
    242         }
    243         else if ((rep->getUB() * lb2) >= (rep->getLB() * (lb2 + 1) - 1))
    244         {
    245             return new Rep(rep->getRE(), rep->getLB() * lb2, ubCombine(rep->getUB(), ub2));
    246         }
    247         else
    248         {
    249             return new Rep(rep, lb2, ub2);
    250         }
    251     }
    252     else
    253     {
    254         if (Seq* seq = dynamic_cast<Seq*>(re))
    255         {
    256             if(seq->GetREList()->size() == 0)
    257             {
    258                 return seq;
    259             }
    260         }
    261 
    262         if ((lb2 == 0) && (ub2 == 0))
    263         {
    264             return new Seq();
    265         }
    266         else if ((lb2 == 1) && (ub2 == 1))
    267         {
    268             return re;
    269         }
    270         else
    271         {
    272             return new Rep(re, lb2, ub2);
    273         }
    274     }
    275 }
  • icGREP/icgrep-devel/icgrep/re_simplifier.h

    r3935 r4182  
    44//Regular Expressions
    55#include "re_re.h"
    6 #include "re_cc.h"
    7 #include "re_name.h"
    8 #include "re_start.h"
    9 #include "re_end.h"
    106#include "re_seq.h"
    11 #include "re_alt.h"
    12 #include "re_rep.h"
    13 
    14 #include <algorithm>
    157#include <list>
    168
    17 class RE_Simplifier
    18 {
     9class RE_Simplifier {
     10    typedef RE::Vector Vector;
    1911public:
    20     static RE* mkSeq(Seq::Type type, std::list<RE*>* re_list);
    21     static RE* mkRep(RE* re, int lb2, int ub2);
    22     static RE* mkAlt(std::list<RE*>* re_list);
    23     static RE* simplify(RE* re);
     12    static RE * makeAlt(Vector & list);
     13    static RE * makeSeq(const Seq::Type type, Vector & list);
     14    static RE * makeRep(RE * re, const int lb2, const int ub2);
     15    static RE * simplify(RE* re);
    2416private:
    25     static std::list<RE*>* mkSeqList(std::list<RE*>* re_list);
    26     static std::list<RE*>* mkSeqList_helper(std::list<RE*>* ret_list, std::list<RE*>* re_list);
    27     static std::list<RE*>* mkAltList(std::list<RE*>* re_list);
    28     static std::list<RE*>* mkAltList_helper(std::list<RE*>* ret_list, std::list<RE*>* re_list);
    29     static int ubCombine(int h1, int h2);
     17    static int ubCombine(const int h1, const int h2);
    3018};
    3119
  • icGREP/icgrep-devel/icgrep/utf8_encoder.cpp

    r4003 r4182  
    88
    99
    10 RE* UTF8_Encoder::toUTF8(RE* re)
    11 {
    12     RE* retVal = 0;
    13 
    14     if (Alt* re_alt = dynamic_cast<Alt*>(re))
    15     {
    16         std::list<RE*> re_list;
    17         std::list<RE*>::reverse_iterator rit = re_alt->GetREList()->rbegin();
    18 
    19         for (rit = re_alt->GetREList()->rbegin(); rit != re_alt->GetREList()->rend(); ++rit)
    20         {
    21             re_list.push_back(toUTF8(*rit));
    22         }
    23 
    24         retVal = new Alt(&re_list);
    25     }
    26     else if (Seq* re_seq = dynamic_cast<Seq*>(re))
    27     {
    28 
    29         std::list<RE*> re_list;
    30         std::list<RE*>::iterator it;
    31 
    32         for (it = re_seq->GetREList()->begin(); it != re_seq->GetREList()->end(); ++it)
    33         {
    34             //If this is a previously encoded Unicode byte sequence.
    35             if (re_seq->getType() == Seq::Byte)
    36             {
    37                 if (CC* seq_cc = dynamic_cast<CC*>(*it))
    38                 {
    39                     CharSetItem item = seq_cc->getItems().front();
    40                     re_list.push_front(new CC(item.lo_codepoint));
     10RE* UTF8_Encoder::toUTF8(RE* re) {
     11
     12    RE* retVal = nullptr;
     13
     14    if (Alt* re_alt = dynamic_cast<Alt*>(re)) {
     15
     16        Alt * new_alt = new Alt();
     17        for (RE * re : *re_alt) {
     18            new_alt->push_back(toUTF8(re));
     19        }
     20        retVal = new_alt;
     21    }
     22    else if (Seq * re_seq = dynamic_cast<Seq*>(re)) {
     23
     24        Seq * new_seq = new Seq(re_seq->getType());
     25        //If this is a previously encoded Unicode byte sequence.
     26        if (re_seq->getType() == Seq::Byte) {
     27            // Should we be throwing an error here? no byte sequences should exist in the code.
     28            // The parser should now convert them to UNICODE code points.
     29            for (RE * re : *re_seq) {
     30                if (CC * cc = dynamic_cast<CC*>(re)) {
     31                    const CharSetItem & item = cc->getItems().front();
     32                    new_seq->push_back(new CC(item.lo_codepoint));
    4133                }
    4234            }
    43             else
    44             {
    45                 re_list.push_front(toUTF8(*it));
     35        }
     36        else {
     37            for (RE * re : *re_seq) {
     38                new_seq->push_back(toUTF8(re));
    4639            }
    4740        }
    48 
    49         Seq* new_seq = new Seq(&re_list);
    50         new_seq->setType(re_seq->getType());
    5141        retVal = new_seq;
    5242    }
     
    6151            retVal = rangeToUTF8(re_cc->getItems().front());
    6252        }
    63         else if (re_cc->getItems().size() > 1)
    64         {           
    65             std::list<RE*> re_list;
    66             for (int i = 0; i < re_cc->getItems().size(); i++)
    67             {
    68                 re_list.push_back(rangeToUTF8(re_cc->getItems().at(i)));
     53        else if (re_cc->getItems().size() > 1) {
     54            RE::Vector re_list;
     55            for (auto & item : re_cc->getItems()) {
     56                re_list.push_back(rangeToUTF8(item));
    6957            }
    70             retVal = RE_Simplifier::mkAlt(&re_list);
    71             //retVal = new Alt(&re_list);
     58            retVal = RE_Simplifier::makeAlt(re_list);
    7259        }
    7360    }
     
    7966        retVal = name;
    8067    }
    81     else if (Start* re_start = dynamic_cast<Start*>(re))
     68    else if (dynamic_cast<Start*>(re))
    8269    {
    8370        retVal = new Start();
    8471    }
    85     else if (End* re_end = dynamic_cast<End*>(re))
     72    else if (dynamic_cast<End*>(re))
    8673    {
    8774        retVal = new End();
     
    9178}
    9279
    93 RE* UTF8_Encoder::rangeToUTF8(CharSetItem item)
    94 {
     80RE * UTF8_Encoder::rangeToUTF8(const CharSetItem & item) {
    9581    int u8len_lo = u8len(item.lo_codepoint);
    9682    int u8len_hi = u8len(item.hi_codepoint);
     
    10490        lo_item.lo_codepoint = item.lo_codepoint;
    10591        lo_item.hi_codepoint = m;
    106         alt->AddREListItem(rangeToUTF8(lo_item));
     92        alt->push_back(rangeToUTF8(lo_item));
    10793        CharSetItem hi_item;
    10894        hi_item.lo_codepoint = m + 1;
    10995        hi_item.hi_codepoint = item.hi_codepoint;
    110         alt->AddREListItem(rangeToUTF8(hi_item));
     96        alt->push_back(rangeToUTF8(hi_item));
    11197
    11298        return alt;
     
    131117        Seq* seq = new Seq();
    132118        seq->setType((u8Prefix(hbyte) ? Seq::Byte : Seq::Normal));
    133         seq->AddREListItem(makeByteClass(hbyte));
    134         seq->AddREListItem(rangeToUTF8_helper(lo, hi, n+1, hlen));
     119        seq->push_back(makeByteClass(hbyte));
     120        seq->push_back(rangeToUTF8_helper(lo, hi, n+1, hlen));
    135121        return seq;
    136122    }
     
    144130
    145131            Alt* alt = new Alt();
    146             alt->AddREListItem(rangeToUTF8_helper(hi_floor, hi, n, hlen));
    147             alt->AddREListItem(rangeToUTF8_helper(lo, hi_floor - 1, n, hlen));
     132            alt->push_back(rangeToUTF8_helper(hi_floor, hi, n, hlen));
     133            alt->push_back(rangeToUTF8_helper(lo, hi_floor - 1, n, hlen));
    148134            return alt;
    149135        }
     
    153139
    154140            Alt* alt = new Alt();
    155             alt->AddREListItem(rangeToUTF8_helper(low_ceil + 1, hi, n, hlen));
    156             alt->AddREListItem(rangeToUTF8_helper(lo, low_ceil, n, hlen));
     141            alt->push_back(rangeToUTF8_helper(low_ceil + 1, hi, n, hlen));
     142            alt->push_back(rangeToUTF8_helper(lo, low_ceil, n, hlen));
    157143            return alt;
    158144        }
     
    161147            Seq* seq = new Seq();
    162148            seq->setType((u8Prefix(hbyte) ? Seq::Byte : Seq::Normal));
    163             seq->AddREListItem(makeByteRange(lbyte, hbyte));
    164             seq->AddREListItem(rangeToUTF8_helper(lo, hi, n + 1, hlen));
     149            seq->push_back(makeByteRange(lbyte, hbyte));
     150            seq->push_back(rangeToUTF8_helper(lo, hi, n + 1, hlen));
    165151            return seq;
    166152        }
  • icGREP/icgrep-devel/icgrep/utf8_encoder.h

    r3961 r4182  
    2323{
    2424public:
    25     static RE* toUTF8(RE* re);
     25    static RE* toUTF8(RE * re);
    2626private:
    27     static RE* rangeToUTF8(CharSetItem item);
     27    static RE* rangeToUTF8(const CharSetItem &item);
    2828    static RE* rangeToUTF8_helper(int lo, int hi, int n, int hlen);
    2929    static CC* makeByteClass(int byteval);
Note: See TracChangeset for help on using the changeset viewer.