#ifndef PIRAHA_HPP #define PIRAHA_HPP #include #include #include #include #include #include namespace piraha { const int max_int = 10000; using std::map; using std::vector; inline char uc_(char a) { if(a >= 'a' && a <= 'z') return a + 'A' - 'a'; else return a; } inline char lc_(char a) { if(a >= 'A' && a <= 'Z') return a + 'a' - 'A'; else return a; } class Group { public: std::string pattern; const char *input; int start_,end_; vector > children; Group(const char *p,const char *value) : pattern(p), input(value), start_(0) { for(end_=0;value[end_] != '\0';end_++); } Group(std::string p,const char *input_) : pattern(p), input(input_), start_(0), end_(0), children() {} Group(std::string p,const char *input_,int s,int e, vector > ch) : pattern(p), input(input_), start_(s), end_(e), children(ch) {} virtual ~Group() {} int start() { return start_; } int end() { return end_; } int childCount(), line(); std::string getPatternName(); std::string substring(); smart_ptr child(int i); void dump(std::ostream& o=std::cout); void dump(int n,std::ostream& o,int indent=0); void dumpPerl(std::ostream&o=std::cout); void dumpPerl(std::ostream&o,int indent); int groupCount() { return children.size(); } smart_ptr group(int i) { return children[i]; } smart_ptr group(const char *nm,int ix=0) { for(unsigned int i=0;igetPatternName() == nm) { if(ix == 0) { return children[i]; } ix--; } } smart_ptr ret; return ret; } }; class Grammar; class Matcher; class Pattern { public: virtual bool match(Matcher *m)=0; Pattern() {} virtual ~Pattern() {} virtual std::string fmt() { return "blank"; } virtual void insert(std::ostream& o) { o << "{?}"; } }; inline std::ostream& operator<<(std::ostream& o,Pattern& p) { p.insert(o); return o; } class JMap { map > m; public: JMap() : m() {} smart_ptr get(std::string key) { typedef map >::iterator mit; mit it = m.find(key); mit me = m.end(); if(it == me) { return NULL; } smart_ptr res = m[key]; assert(res.valid()); return res; } void put(std::string key,smart_ptr p) { assert(p.valid()); m[key] = p; } friend std::ostream& operator<<(std::ostream&,JMap&); }; inline std::ostream& operator<<(std::ostream& o,JMap& jmap) { typedef map >::iterator mit; mit mb = jmap.m.begin(); mit me = jmap.m.end(); o << "{"; for(mit i = mb; i != me;++i) { o << "[" << i->first << "]"; } o << "}"; return o; } class Grammar { public: Grammar() {} virtual ~Grammar() {} JMap patterns; std::string default_rule; }; class Seq : public Pattern { vector > patterns; public: Seq(Pattern *p,...); Seq(vector > patterns,bool ign,bool show); virtual ~Seq() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { for(unsigned int i=0;i > patterns; bool ignCase, igcShow; Or(bool ign,bool show) : ignCase(ign), igcShow(show) {} Or(Pattern *p,...); virtual ~Or() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { o << "("; for(unsigned int i=0;i 0) o << "|"; o << *patterns[i]; } o << ")"; } }; class Literal : public Pattern { public: const char c; Literal(char b) : c(b) {} bool match(Matcher *m); std::string fmt() { std::string s = "literal("; s += c+")"; return s; } virtual void insert(std::ostream& o) { if(c == '\n') o << "\\n"; else if(c == '\r') o << "\\r"; else if(c == '\t') o << "\\t"; else if(c == '\b') o << "\\b"; else if(c >= 'a' && c <= 'z') o << c; else if(c >= 'A' && c <= 'Z') o << c; else if(c >= '0' && c <= '9') o << c; else o << "\\" << c; } }; class ILiteral : public Pattern { public: const char lc,uc; ILiteral(char b); bool match(Matcher *m); std::string fmt() { std::string s = "Iliteral("; s += lc; s += ","; s += uc; s += ")"; return s; } virtual void insert(std::ostream& o) { char c = lc; if(lc != uc) o << "[" << lc << uc << "]"; else if(c == '\n') o << "\\n"; else if(c == '\r') o << "\\r"; else if(c == '\t') o << "\\t"; else if(c == '\b') o << "\\b"; else if(c >= 'a' && c <= 'z') o << c; else if(c >= 'A' && c <= 'Z') o << c; else if(c >= '0' && c <= '9') o << c; else o << "\\" << c; } }; class Lookup : public Pattern { smart_ptr gram; std::string name; bool capture; public: Lookup(std::string s,smart_ptr g); virtual ~Lookup() {} bool match(Matcher *m); std::string fmt() { return "Literal:"+name; } virtual void insert(std::ostream& o) { o << "{" << name << "}"; } }; class Nothing : public Pattern { public: Nothing() {} bool match(Matcher *m) { return true; } }; class Start : public Pattern { public: Start() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { o << "^"; } }; class End : public Pattern { public: End() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { o << "$"; } }; class Dot : public Pattern { public: Dot() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { o << "."; } }; class Multi : public Pattern { const int minv,maxv; public: smart_ptr pattern; Multi(int min_,int max_) : minv(min_), maxv(max_), pattern(NULL) {} Multi(Pattern *p,int min_,int max_) : minv(min_), maxv(max_), pattern(p) {} virtual ~Multi() {} bool match(Matcher *m); virtual void insert(std::ostream& o) { o << *pattern << "{" << minv << "," << maxv << "}"; } }; class Range : public Pattern { public: char lo,hi; bool match(Matcher *m); Range(char lo_,char hi_) : lo(lo_), hi(hi_) {} }; class Bracket : public Pattern { public: bool neg; vector > ranges; Bracket() : neg(false) {} virtual ~Bracket() {} Bracket(bool b); Bracket *addRange(char lo,char hi); Bracket *addRange(char lo,char hi,bool ign); bool match(Matcher *m); virtual void insert(std::ostream& o); }; class NegLookAhead : public Pattern { public: smart_ptr pattern; NegLookAhead(smart_ptr p) : pattern(p) {} virtual ~NegLookAhead() {} bool match(Matcher *m); }; class LookAhead : public Pattern { public: smart_ptr pattern; LookAhead(smart_ptr p) : pattern(p) {} virtual ~LookAhead() {} bool match(Matcher *m) { assert(false); }//TODO: Fill in }; class Boundary : public Pattern { virtual bool match(Matcher *m); }; class Break : public Pattern { virtual bool match(Matcher *m) { assert(false); }//TODO: Fill in }; class BackRef : public Pattern { public: int index; bool ignCase; BackRef(int in,bool ign) : index(in), ignCase(ign) {} virtual bool match(Matcher *m) { assert(false); }//TODO: Fill in }; class AutoGrammar { public: static smart_ptr reparserGenerator(); static smart_ptr fileParserGenerator(); }; class Matcher : public Group { public: Matcher(smart_ptr g,const char *pat_,const char *input_,int input_size=-1); virtual ~Matcher() {} const char *input; smart_ptr g; int input_size; int pos; int max_pos; const char *pat; bool matches(); Bracket expected; void showError(); std::string inrule; std::string inrule_max; int err_pos; void fail(Bracket *ex); void fail(char lo,char hi); }; extern smart_ptr pegGrammar; extern smart_ptr compile(smart_ptr g,bool ignCase,smart_ptr gram); extern void compileFile(smart_ptr g,const char *buffer,signed long buffersize=-1); void compile(smart_ptr thisg,std::string name,std::string pattern); void compile(smart_ptr thisg,std::string name,smart_ptr pattern); void insertc(std::ostream& o,char c); } #endif