From cc9f08d733c594e8f56a232210992dd0bab2b8b0 Mon Sep 17 00:00:00 2001 From: helly Date: Sun, 20 Jan 2008 21:25:30 +0000 Subject: [PATCH] - Added re2c:cond:divider and re2c:con:goto inplace configuration. --- re2c/CHANGELOG | 1 + re2c/code.cc | 14 +- re2c/globals.h | 2 + re2c/htdocs/index.html | 1 + re2c/htdocs/manual.html | 9 + re2c/main.cc | 2 + re2c/test/condition_14.cgif.c | 441 +++++++++++++++++++++++++++++++++ re2c/test/condition_14.cgif.re | 198 +++++++++++++++ 8 files changed, 665 insertions(+), 3 deletions(-) create mode 100755 re2c/test/condition_14.cgif.c create mode 100755 re2c/test/condition_14.cgif.re diff --git a/re2c/CHANGELOG b/re2c/CHANGELOG index 2a097019..1c19c508 100644 --- a/re2c/CHANGELOG +++ b/re2c/CHANGELOG @@ -3,6 +3,7 @@ Version 0.13.2 (2007-??-??) - Added support for '=>' style rules. - Added support for ':=' style rules. - Added support for ':=>' style rules. +- Added re2c:cond:divider and re2c:con:goto inplace configuration. Version 0.13.1 (2007-08-24) --------------------------- diff --git a/re2c/code.cc b/re2c/code.cc index 64af1ab0..01306b0b 100644 --- a/re2c/code.cc +++ b/re2c/code.cc @@ -688,9 +688,9 @@ void Rule::emit(std::ostream &o, uint ind, bool &) const o << indent(ind); if (rule->code->autogen) { - // TODO: When an empty rule is present, we need to go there. So we need - // an option to generate a 'continue' rather than the 'goto' line. - o << "goto " << condPrefix << rule->code->newcond << ";"; + std::string condLabel(condPrefix); + condLabel += rule->code->newcond->to_string(); + o << replaceParam(condGoto, condGotoParam, condLabel); } else { @@ -2138,6 +2138,14 @@ void Scanner::config(const Str& cfg, const Str& val) { condDividerParam = strVal; } + else if (cfg.to_string() == "cond:goto") + { + condGoto = strVal; + } + else if (cfg.to_string() == "cond:goto@cond") + { + condGotoParam = strVal; + } else if (cfg.to_string() == "define:YYFILL@len") { yyFillLength = strVal; diff --git a/re2c/globals.h b/re2c/globals.h index b04b0ffe..fd04656d 100644 --- a/re2c/globals.h +++ b/re2c/globals.h @@ -45,6 +45,8 @@ extern std::string condPrefix; extern std::string condEnumPrefix; extern std::string condDivider; extern std::string condDividerParam; +extern std::string condGoto; +extern std::string condGotoParam; extern std::string yychConversion; extern std::string yyFillLength; extern std::string yySetConditionParam; diff --git a/re2c/htdocs/index.html b/re2c/htdocs/index.html index 977043da..ff9c1762 100755 --- a/re2c/htdocs/index.html +++ b/re2c/htdocs/index.html @@ -84,6 +84,7 @@ fixes which were incorporated. Added support for '=>' style rules.
  • Added support for ':=' style rules.
  • Added support for ':=>' style rules.
  • +
  • Added re2c:cond:divider and re2c:con:goto inplace configuration.
  • 2007-08-24: 0.13.1

    diff --git a/re2c/htdocs/manual.html b/re2c/htdocs/manual.html index c263e038..4ce80fa5 100755 --- a/re2c/htdocs/manual.html +++ b/re2c/htdocs/manual.html @@ -421,6 +421,15 @@ using re2c:cond:divider@cond.
    re2c:cond:divider@cond = @@ ;
    Specify the placeholder that will be replaced with the condition name in re2c:cond:divider\fP.
    +
    re2c:cond:goto = "goto @@;" ;
    +
    Allows to customize the condition goto statements used with ':=>' style rules. +You can use '@@' to put the name of the condition or ustomize the plaeholder +using re2c:cond:goto@cond. You can also change this to 'continue;', +which would allow you to continue with the next loop cycle including any code +between loop start and re2c block.
    +
    re2c:cond:goto@cond = @@ ;
    +
    Spcifies the placeholder that will be replaced with the condition label +in re2c:cond:goto.
    re2c:indent:top = 0 ;
    Specifies the minimum number of indendation to use. Requires a numeric value greater than or equal zero.
    diff --git a/re2c/main.cc b/re2c/main.cc index a7c9df09..9842d7e9 100644 --- a/re2c/main.cc +++ b/re2c/main.cc @@ -61,6 +61,8 @@ std::string condPrefix("yyc_"); std::string condEnumPrefix("yyc"); std::string condDivider("/* *********************************** */"); std::string condDividerParam("@@"); +std::string condGoto("goto @@;"); +std::string condGotoParam("@@"); std::string yychConversion(""); std::string yyFillLength("@@"); std::string yySetConditionParam("@@"); diff --git a/re2c/test/condition_14.cgif.c b/re2c/test/condition_14.cgif.c new file mode 100755 index 00000000..8218f903 --- /dev/null +++ b/re2c/test/condition_14.cgif.c @@ -0,0 +1,441 @@ +/* Generated by re2c */ +#include +#include +#include + +#define BSIZE 8192 + + +enum ScanContition { + EStateNormal, + EStateComment, + EStateSkiptoeol, + EStateString, +}; + + +typedef struct Scanner +{ + FILE *fp; + unsigned char *cur, *tok, *lim, *eof; + unsigned char buffer[BSIZE]; + unsigned char yych; + enum ScanContition cond; + int state; +} Scanner; + +size_t fill(Scanner *s, size_t len) +{ + size_t got = ~0, cnt; + + if (!s->eof && s->lim - s->tok < len) + { + if (s->tok > s->buffer) + { + cnt = s->tok - s->buffer; + memcpy(s->buffer, s->tok, s->lim - s->tok); + s->tok -= cnt; + s->cur -= cnt; + s->lim -= cnt; + cnt = &s->buffer[BSIZE] - s->lim; + } + else + { + cnt = BSIZE; + } + if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt) + { + s->eof = &s->lim[got]; + } + s->lim += got; + } + if (s->eof && s->cur + len > s->eof) + { + return ~0; /* not enough input data */ + } + return got; +} + +size_t init(Scanner *s) +{ + s->cur = s->tok = s->lim = s->buffer; + s->eof = 0; + s->cond = EStateNormal; + s->state = -1; + + return fill(s, 0); +} + +void fputl(const char *s, size_t len, FILE *stream) +{ + while(len-- > 0) + { + fputc(*s++, stream); + } +} + +void scan(Scanner *s) +{ + s->tok = s->cur; + + static void *yystable[] = { + &&yyFillLabel0, + &&yyFillLabel1, + &&yyFillLabel2, + &&yyFillLabel3, + }; + + if(s->state < 0) goto yy0; + goto *yystable[s->state]; + for(;;) + { + s->tok = s->cur; + + { + + static void *yyctable[4] = { + &&yyc_Normal, + &&yyc_Comment, + &&yyc_Skiptoeol, + &&yyc_String, + }; +yy0: + goto *yyctable[s->cond]; +/* *********************************** */ +yyc_Comment: + + s->state = 0; + if((s->lim - s->cur) < 2) if(fill(s, 2) == ~0) break; +yyFillLabel0: + s->yych = *s->cur; + if(s->yych != '*') goto yy4; + ++s->cur; + if((s->yych = *s->cur) == '/') goto yy5; +yy3: + continue; +yy4: + s->yych = *++s->cur; + goto yy3; +yy5: + ++s->cur; + s->cond = EStateNormal; + continue; +/* *********************************** */ +yyc_Normal: + s->state = 1; + if((s->lim - s->cur) < 4) if(fill(s, 4) == ~0) break; +yyFillLabel1: + s->yych = *s->cur; + { + static void *yytarget[256] = { + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy13, &&yy15, &&yy15, &&yy15, &&yy15, &&yy12, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy11, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy9, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, + &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15, &&yy15 + }; + goto *yytarget[s->yych]; + } +yy9: + s->yych = *(s->tok = ++s->cur); + if(s->yych == '?') goto yy26; +yy10: + fputc(s->cur[-1], stdout); + continue; +yy11: + s->yych = *++s->cur; + if(s->yych == '*') goto yy24; + if(s->yych == '/') goto yy22; + goto yy10; +yy12: + s->yych = *(s->tok = ++s->cur); + if(s->yych == '"') goto yy16; + if(s->yych == '\\') goto yy18; + goto yy10; +yy13: + ++s->cur; + s->cond = EStateString; + fputc(s->cur[-1], stdout); + continue; +yy15: + s->yych = *++s->cur; + goto yy10; +yy16: + s->yych = *++s->cur; + if(s->yych == '\'') goto yy20; +yy17: + s->cur = s->tok; + goto yy10; +yy18: + s->yych = *++s->cur; + if(s->yych != '"') goto yy17; + s->yych = *++s->cur; + if(s->yych != '\'') goto yy17; +yy20: + ++s->cur; + fputl("'\"'", 3, stdout); + continue; +yy22: + ++s->cur; + s->cond = EStateSkiptoeol; + continue; +yy24: + ++s->cur; + s->cond = EStateComment; + continue; +yy26: + s->yych = *++s->cur; + { + static void *yytarget[256] = { + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy41, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy39, + &&yy27, &&yy29, &&yy17, &&yy17, &&yy17, &&yy43, &&yy17, &&yy37, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy31, &&yy35, &&yy33, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, + &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17, &&yy17 + }; + goto *yytarget[s->yych]; + } +yy27: + ++s->cur; + fputc('[', stdout); + continue; +yy29: + ++s->cur; + fputc(']', stdout); + continue; +yy31: + ++s->cur; + fputc('{', stdout); + continue; +yy33: + ++s->cur; + fputc('}', stdout); + continue; +yy35: + ++s->cur; + fputc('#', stdout); + continue; +yy37: + ++s->cur; + fputc('\\', stdout); + continue; +yy39: + ++s->cur; + fputc('^', stdout); + continue; +yy41: + ++s->cur; + fputc('|', stdout); + continue; +yy43: + ++s->cur; + fputc('~', stdout); + continue; +/* *********************************** */ +yyc_Skiptoeol: + s->state = 2; + if((s->lim - s->cur) < 5) if(fill(s, 5) == ~0) break; +yyFillLabel2: + s->yych = *s->cur; + { + static void *yytarget[256] = { + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy51, &&yy53, &&yy53, &&yy50, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy47, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy49, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, + &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53, &&yy53 + }; + goto *yytarget[s->yych]; + } +yy47: + s->yych = *(s->tok = ++s->cur); + if(s->yych == '?') goto yy60; +yy48: + continue; +yy49: + s->yych = *(s->tok = ++s->cur); + if(s->yych == 0x0A) goto yy58; + if(s->yych == 0x0D) goto yy56; + goto yy48; +yy50: + s->yych = *++s->cur; + if(s->yych == 0x0A) goto yy54; + goto yy48; +yy51: + ++s->cur; + s->cond = EStateNormal; + fputc('\n', stdout); + continue; +yy53: + s->yych = *++s->cur; + goto yy48; +yy54: + ++s->cur; + s->cond = EStateNormal; + fputc('\r', stdout); + fputc('\n', stdout); + continue; +yy56: + s->yych = *++s->cur; + if(s->yych == 0x0A) goto yy58; +yy57: + s->cur = s->tok; + goto yy48; +yy58: + ++s->cur; + continue; +yy60: + s->yych = *++s->cur; + if(s->yych != '/') goto yy57; + s->yych = *++s->cur; + if(s->yych == 0x0A) goto yy63; + if(s->yych != 0x0D) goto yy57; + s->yych = *++s->cur; + if(s->yych != 0x0A) goto yy57; +yy63: + ++s->cur; + continue; +/* *********************************** */ +yyc_String: + s->state = 3; + if((s->lim - s->cur) < 2) if(fill(s, 2) == ~0) break; +yyFillLabel3: + s->yych = *s->cur; + if(s->yych == '"') goto yy69; + if(s->yych != '\\') goto yy71; + ++s->cur; + if((s->yych = *s->cur) != 0x0A) goto yy72; +yy68: + fputc(s->cur[-1], stdout); + continue; +yy69: + ++s->cur; + s->cond = EStateNormal; + fputc(s->cur[-1], stdout); + continue; +yy71: + s->yych = *++s->cur; + goto yy68; +yy72: + ++s->cur; + fputl((const char*)s->cur-2, 2, stdout); + continue; + } + + } +} + +int main(int argc, char **argv) +{ + Scanner in; + + 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; + } + + if (init(&in) > 0) + { + scan(&in); + } + + if (in.fp != stdin) + { + fclose(in.fp); + } + return 0; +} diff --git a/re2c/test/condition_14.cgif.re b/re2c/test/condition_14.cgif.re new file mode 100755 index 00000000..5e9d168a --- /dev/null +++ b/re2c/test/condition_14.cgif.re @@ -0,0 +1,198 @@ +#include +#include +#include + +#define BSIZE 8192 + +/*!types:re2c */ + +typedef struct Scanner +{ + FILE *fp; + unsigned char *cur, *tok, *lim, *eof; + unsigned char buffer[BSIZE]; + unsigned char yych; + enum ScanContition cond; + int state; +} Scanner; + +size_t fill(Scanner *s, size_t len) +{ + size_t got = ~0, cnt; + + if (!s->eof && s->lim - s->tok < len) + { + if (s->tok > s->buffer) + { + cnt = s->tok - s->buffer; + memcpy(s->buffer, s->tok, s->lim - s->tok); + s->tok -= cnt; + s->cur -= cnt; + s->lim -= cnt; + cnt = &s->buffer[BSIZE] - s->lim; + } + else + { + cnt = BSIZE; + } + if ((got = fread(s->lim, 1, cnt, s->fp)) != cnt) + { + s->eof = &s->lim[got]; + } + s->lim += got; + } + if (s->eof && s->cur + len > s->eof) + { + return ~0; /* not enough input data */ + } + return got; +} + +size_t init(Scanner *s) +{ + s->cur = s->tok = s->lim = s->buffer; + s->eof = 0; + s->cond = EStateNormal; + s->state = -1; + + return fill(s, 0); +} + +void fputl(const char *s, size_t len, FILE *stream) +{ + while(len-- > 0) + { + fputc(*s++, stream); + } +} + +void scan(Scanner *s) +{ + s->tok = s->cur; +/*!re2c +re2c:define:YYGETSTATE = "s->state"; +re2c:define:YYGETSTATE:naked = 1; +re2c:define:YYCONDTYPE = ScanContition; +re2c:indent:top = 1; +re2c:cond:goto = "continue;"; +*/ +/*!getstate:re2c */ + 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->tok; +re2c:define:YYFILL@len = #; +re2c:define:YYFILL:naked = 1; +re2c:define:YYFILL = "if(fill(s, #) == ~0) break;"; +re2c:define:YYSETSTATE@state = #; +re2c:define:YYSETSTATE = "s->state = #;"; +re2c:define:YYSETCONDITION = "s->cond = #;"; +re2c:define:YYSETCONDITION@cond = #; +re2c:define:YYGETCONDITION = s->cond; +re2c:define:YYGETCONDITION:naked = 1; +re2c:variable:yych = s->yych; +re2c:yych:emit = 0; +re2c:indent:top = 2; +re2c:condenumprefix = EState; + + "??(" := + fputc('[', stdout); + continue; + "??)" := + fputc(']', stdout); + continue; + "??<" := + fputc('{', stdout); + continue; + "??>" := + fputc('}', stdout); + continue; + "??=" := + fputc('#', stdout); + continue; + "??/" := + fputc('\\', stdout); + continue; + "??'" := + fputc('^', stdout); + continue; + "??!" := + fputc('|', stdout); + continue; + "??-" := + fputc('~', stdout); + continue; + "/*" :=> Comment + "//" :=> Skiptoeol + "'\\\"'"|"'\"'" := + fputl("'\"'", 3, stdout); + continue; + '"' => String := + fputc(s->cur[-1], stdout); + continue; + [^] := + fputc(s->cur[-1], stdout); + continue; + "*" "/" :=> Normal + [^] :=> Comment + "??/" "\r"? "\n" :=> Skiptoeol + "\\" "\r"? "\n" :=> Skiptoeol + "\r" "\n" => Normal := + fputc('\r', stdout); + fputc('\n', stdout); + continue; + "\n" => Normal := + fputc('\n', stdout); + continue; + [^] :=> Skiptoeol + '\\' . := + fputl((const char*)s->cur-2, 2, stdout); + continue; + '"' => Normal := + fputc(s->cur[-1], stdout); + continue; + [^] := + fputc(s->cur[-1], stdout); + continue; +*/ + } +} + +int main(int argc, char **argv) +{ + Scanner in; + + 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; + } + + if (init(&in) > 0) + { + scan(&in); + } + + if (in.fp != stdin) + { + fclose(in.fp); + } + return 0; +} -- 2.50.1