From: helly Date: Mon, 23 Apr 2007 22:18:43 +0000 (+0000) Subject: - Add -cs support X-Git-Tag: 0.13.6~181 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a7e8d8a6b9305ee8a8b46278a5a5bf5aa41dc67a;p=re2c - Add -cs support --- diff --git a/re2c/code.cc b/re2c/code.cc index 828f4aa9..8a16ad42 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -1586,7 +1586,6 @@ void DFA::emit(std::ostream &o, uint& ind, const RegExpMap* specMap, const std:: } if (bProlog) { - genCondTable(o, ind, *specMap); genGetState(o, ind, start_label); genCondGoto(o, ind, *specMap); @@ -1663,23 +1662,55 @@ void genGetState(std::ostream &o, uint& ind, uint start_label) } } +static RegExpIndices genCondList(const RegExpMap& specMap) +{ + RegExpIndices vCondList; + + for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) + { + vCondList.push_back(it->first); + } + + return vCondList; +} + void genCondTable(std::ostream &o, uint ind, const RegExpMap& specMap) { - if (cFlag && !bWroteCondCheck && gFlag) + if (cFlag && !bWroteCondCheck && gFlag && specMap.size()) { o << indent(ind++) << "static void *" << mapCodeName["yyctable"] << "[" << specMap.size() << "] = {\n"; - for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) + RegExpIndices vCondList = genCondList(specMap); + + for(RegExpIndices::const_iterator it = vCondList.begin(); it != vCondList.end(); ++it) { - o << indent(ind) << "&&" << condPrefix << it->first << ",\n"; + o << indent(ind) << "&&" << condPrefix << *it << ",\n"; } o << indent(--ind) << "};\n"; } } +static void genCondGotoSub(std::ostream &o, uint ind, RegExpIndices& vCondList, uint cMin, uint cMax) +{ + if (cMin == cMax) + { + o << indent(ind) << "goto " << condPrefix << vCondList[cMin] << ";\n"; + } + else + { + uint cMid = cMin + ((cMax - cMin + 1) / 2); + + o << indent(ind) << "if (" << mapCodeName["YYCONDITION"] << " < " << cMid << ") {\n"; + genCondGotoSub(o, ind + 1, vCondList, cMin, cMid - 1); + o << indent(ind) << "} else {\n"; + genCondGotoSub(o, ind + 1, vCondList, cMid, cMax); + o << indent(ind) << "}\n"; + } +} + void genCondGoto(std::ostream &o, uint ind, const RegExpMap& specMap) { - if (cFlag && !bWroteCondCheck) + if (cFlag && !bWroteCondCheck && specMap.size()) { if (gFlag) { @@ -1687,12 +1718,22 @@ void genCondGoto(std::ostream &o, uint ind, const RegExpMap& specMap) } else { - o << indent(ind) << "switch(" << mapCodeName["YYCONDITION"] << ") {\n"; - for(RegExpMap::const_iterator it = specMap.begin(); it != specMap.end(); ++it) + RegExpIndices vCondList = genCondList(specMap); + + if (sFlag) { - o << indent(ind) << "case " << it->first << ": goto " << condPrefix << it->first << ";\n"; + genCondGotoSub(o, ind, vCondList, 0, vCondList.size() - 1); + } + else + { + o << indent(ind) << "switch(" << mapCodeName["YYCONDITION"] << ") {\n"; + + for(RegExpIndices::const_iterator it = vCondList.begin(); it != vCondList.end(); ++it) + { + o << indent(ind) << "case " << *it << ": goto " << condPrefix << *it << ";\n"; + } + o << indent(ind) << "}\n"; } - o << indent(ind) << "}\n"; } bWroteCondCheck = true; } diff --git a/re2c/re.h b/re2c/re.h index 89c4d0fc..9dd67690 100644 --- a/re2c/re.h +++ b/re2c/re.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "token.h" #include "ins.h" #include "globals.h" @@ -489,6 +490,7 @@ private: typedef std::set CondList; typedef std::pair NRegExp; typedef std::map RegExpMap; +typedef std::vector RegExpIndices; typedef std::list RuleOpList; extern void genCode(std::ostream&, uint&, RegExp*, const RegExpMap*, const std::string&, bool); diff --git a/re2c/test/condition_05.cs.c b/re2c/test/condition_05.cs.c new file mode 100755 index 00000000..930b4129 --- /dev/null +++ b/re2c/test/condition_05.cs.c @@ -0,0 +1,150 @@ +/* Generated by re2c */ +#line 1 "condition_05.cs.re" +#include +#include +#include + +#define BSIZE 8192 + +typedef struct Scanner +{ + FILE *fp; + unsigned char *cur, *tok, *lim, *eof; + unsigned char buffer[BSIZE]; +} Scanner; + +int fill(Scanner *s, int len) +{ + if (!len) + { + s->cur = s->tok = s->lim = s->buffer; + s->eof = 0; + } + if (!s->eof) + { + int got, cnt = s->tok - s->buffer; + + if (cnt > 0) + { + memcpy(s->buffer, s->tok, s->lim - s->tok); + s->tok -= cnt; + s->cur -= cnt; + s->lim -= cnt; + } + cnt = BSIZE - cnt; + if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt) + { + s->eof = &s->lim[got]; + } + s->lim += got; + } + else if (s->cur + len > s->eof) + { + return 0; /* not enough input data */ + } + return -1; +} + +char scan(Scanner *s) +{ + int state = 1; + + fill(s, 0); + + for(;;) + { + s->tok = s->cur; + +#line 59 "" + { + unsigned char yych; + if (state < 1) { + goto yyc_comment; + } else { + goto yyc_normal; + } +/* *********************************** */ +yyc_comment: + + if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }; + yych = *s->cur; + if(yych != '*') goto yy4; + ++s->cur; + if((yych = *s->cur) == '/') goto yy5; +yy3: +#line 80 "condition_05.cs.re" + { + goto yyc_comment; + } +#line 80 "" +yy4: + yych = *++s->cur; + goto yy3; +yy5: + ++s->cur; +#line 76 "condition_05.cs.re" + { + continue; + } +#line 90 "" +/* *********************************** */ +yyc_normal: + if((s->lim - s->cur) < 2) { if(fill(s, 2) >= 0) break; }; + yych = *s->cur; + if(yych != '/') goto yy11; + ++s->cur; + if((yych = *s->cur) == '*') goto yy12; +yy10: +#line 71 "condition_05.cs.re" + { + fputc(*s->tok, stdout); + continue; + } +#line 104 "" +yy11: + yych = *++s->cur; + goto yy10; +yy12: + ++s->cur; +#line 67 "condition_05.cs.re" + { + goto yyc_comment; + } +#line 114 "" + } +#line 84 "condition_05.cs.re" + + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + if (argc != 2) + { + fprintf(stderr, "%s \n", argv[0]); + return 1;; + } + + memset((char*) &in, 0, sizeof(in)); + + if (!strcmp(argv[1], "-")) + { + in.fp = stdin; + } + else if ((in.fp = fopen(argv[1], "r")) == NULL) + { + fprintf(stderr, "Cannot open file '%s'\n", argv[1]); + return 1; + } + + scan(&in); + + if (in.fp != stdin) + { + fclose(in.fp); + } + return 0; +} diff --git a/re2c/test/condition_05.cs.re b/re2c/test/condition_05.cs.re new file mode 100755 index 00000000..7c702fa2 --- /dev/null +++ b/re2c/test/condition_05.cs.re @@ -0,0 +1,118 @@ +#include +#include +#include + +#define BSIZE 8192 + +typedef struct Scanner +{ + FILE *fp; + unsigned char *cur, *tok, *lim, *eof; + unsigned char buffer[BSIZE]; +} Scanner; + +int fill(Scanner *s, int len) +{ + if (!len) + { + s->cur = s->tok = s->lim = s->buffer; + s->eof = 0; + } + if (!s->eof) + { + int got, cnt = s->tok - s->buffer; + + if (cnt > 0) + { + memcpy(s->buffer, s->tok, s->lim - s->tok); + s->tok -= cnt; + s->cur -= cnt; + s->lim -= cnt; + } + cnt = BSIZE - cnt; + if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt) + { + s->eof = &s->lim[got]; + } + s->lim += got; + } + else if (s->cur + len > s->eof) + { + return 0; /* not enough input data */ + } + return -1; +} + +char scan(Scanner *s) +{ + int state = 1; + + fill(s, 0); + + for(;;) + { + s->tok = s->cur; +/*!re2c + +re2c:define:YYCTYPE = "unsigned char"; +re2c:define:YYCURSOR = s->cur; +re2c:define:YYLIMIT = s->lim; +re2c:define:YYMARKER = s->ptr; +re2c:define:YYFILL = "{ if(fill(s, 2) >= 0) break; }"; +re2c:define:YYCONDITION = state; +re2c:yyfill:parameter = 0; +re2c:indent:top = 2; + + "/*" + { + goto yyc_comment; + } + [^] + { + fputc(*s->tok, stdout); + continue; + } + "*" "/" + { + continue; + } + [^] + { + goto yyc_comment; + } + +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + char c; + + if (argc != 2) + { + fprintf(stderr, "%s \n", argv[0]); + return 1;; + } + + memset((char*) &in, 0, sizeof(in)); + + if (!strcmp(argv[1], "-")) + { + in.fp = stdin; + } + else if ((in.fp = fopen(argv[1], "r")) == NULL) + { + fprintf(stderr, "Cannot open file '%s'\n", argv[1]); + return 1; + } + + scan(&in); + + if (in.fp != stdin) + { + fclose(in.fp); + } + return 0; +}