--- /dev/null
+a.out
+*.temp
+*.diff
+*.o
--- /dev/null
+re2c lesson_002, (c) M. Boerger 2006
+
+In this lesson you will learn how to use multiple scanner blocks and how to
+read the input from a file instead of a zero terminated string. In the end you
+will have a scanner that filters comments out of c source files but keeps re2c
+comments.
+
+The first scanner can be generated with:
+
+ re2c -s -o t.c strip_001.s.re
+
+In the second step we will learn about YYMARKER that stores backtracking
+information and YYCTXMARKER that is used for trailing contexts.
\ No newline at end of file
--- /dev/null
+/* Generated by re2c */
+#line 1 "strip_001.s.re"
+/* re2c lesson_002, strip_001.s, (c) M. Boerger 2006 */
+#line 32 "strip_001.s.re"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define YYMAXFILL 2
+#define BSIZE 128
+
+#if BSIZE < YYMAXFILL
+# error BSIZE must be greater YYMAXFILL
+#endif
+
+#define YYCTYPE char
+#define YYCURSOR s.cur
+#define YYLIMIT s.lim
+#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
+
+typedef struct Scanner
+{
+ FILE *fp;
+ char *cur, *tok, *lim, *eof;
+ char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->tok = s->cur = buf = 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;
+}
+
+int scan(FILE *fp)
+{
+ int res = 0;
+ Scanner s;
+
+ if (!fp)
+ {
+ return 1; /* no file was opened */
+ }
+
+ s.fp = fp;
+
+ fill(&s, 0);
+
+ for(;;)
+ {
+ s.tok = s.cur;
+
+#line 80 "<stdout>"
+ {
+ YYCTYPE yych;
+
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych != '/') goto yy4;
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '*') goto yy5;
+ if(yych == '/') goto yy7;
+yy3:
+#line 113 "strip_001.s.re"
+ { fputc(*s.tok, stdout); continue; }
+#line 93 "<stdout>"
+yy4:
+ yych = *++YYCURSOR;
+ goto yy3;
+yy5:
+ ++YYCURSOR;
+#line 112 "strip_001.s.re"
+ { goto comment; }
+#line 101 "<stdout>"
+yy7:
+ ++YYCURSOR;
+#line 111 "strip_001.s.re"
+ { goto cppcomment; }
+#line 106 "<stdout>"
+ }
+#line 114 "strip_001.s.re"
+
+comment:
+ s.tok = s.cur;
+
+#line 113 "<stdout>"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych != '*') goto yy13;
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '/') goto yy14;
+yy12:
+#line 119 "strip_001.s.re"
+ { goto comment; }
+#line 124 "<stdout>"
+yy13:
+ yych = *++YYCURSOR;
+ goto yy12;
+yy14:
+ ++YYCURSOR;
+#line 118 "strip_001.s.re"
+ { continue; }
+#line 132 "<stdout>"
+ }
+#line 120 "strip_001.s.re"
+
+cppcomment:
+ s.tok = s.cur;
+
+#line 139 "<stdout>"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy20;
+ if(yych != 0x0D) goto yy22;
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == 0x0A) goto yy23;
+yy19:
+#line 125 "strip_001.s.re"
+ { goto cppcomment; }
+#line 151 "<stdout>"
+yy20:
+ ++YYCURSOR;
+yy21:
+#line 124 "strip_001.s.re"
+ { fwrite(s.tok, 1, s.cur - s.tok, stdout); continue; }
+#line 157 "<stdout>"
+yy22:
+ yych = *++YYCURSOR;
+ goto yy19;
+yy23:
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy21;
+ }
+#line 126 "strip_001.s.re"
+
+ }
+
+ if (fp != stdin)
+ {
+ fclose(fp); /* close only if not stdin */
+ }
+ return res; /* return result */
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ {
+ return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
+ }
+ else
+ {
+ fprintf(stderr, "%s <expr>\n", argv[0]);
+ return 1;
+ }
+}
--- /dev/null
+/* re2c lesson_002, strip_001.s, (c) M. Boerger 2006 */
+/*!ignore:re2c
+
+- basic interface for file reading
+ . This scanner will read chunks of input from a file. The easiest way would
+ be to read the whole file into a memory buffer and use that a zero
+ terminated string.
+ . Instead we want to read input chunks of a reasonable size as they are neede
+ by the scanner. Thus we basically need YYFILL(n) to call fread(n).
+ . Before we provide a buffer that we constantly reallocate we instead use
+ one buffer that we get from the stack or global memory just once. When we
+ reach the end of the buffer we simply move the beginning of our input
+ that is somewhere in our buffer to the beginning of our buffer and then
+ append the next chunk of input to the correct end inside our buffer.
+ . As re2c scanners might read more than one character we need to ensure our
+ buffer is long enough. We can use re2c to inform about the maximum size
+ by placing a "!max:re2c" comment somewhere. This gets translated to a
+ "#define YYMAXFILL <n>" line where <n> is the maximum length value. This
+ define can be used as precompiler condition.
+
+- multiple scanner blocks
+ . We use a main scanner block that outputs every input character unless the
+ input is two /s or a / followed by a *. In the lattertwo cases we switch
+ to a special c++ comment and a comment block respectively.
+ . Both special blocks simply detect their end ignore any other character.
+ . The c++ block is a bit special. Since the terminating new line needs to
+ be output and that can either be a new line or a carridge return followed
+ by a new line.
+ . In order to ensure that we do not read behind our buffer we reset the token
+ pointer to the cursor on every scanner run.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*!max:re2c */
+#define BSIZE 128
+
+#if BSIZE < YYMAXFILL
+# error BSIZE must be greater YYMAXFILL
+#endif
+
+#define YYCTYPE char
+#define YYCURSOR s.cur
+#define YYLIMIT s.lim
+#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
+
+typedef struct Scanner
+{
+ FILE *fp;
+ char *cur, *tok, *lim, *eof;
+ char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->tok = s->cur = buf = 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;
+}
+
+int scan(FILE *fp)
+{
+ int res = 0;
+ Scanner s;
+
+ if (!fp)
+ {
+ return 1; /* no file was opened */
+ }
+
+ s.fp = fp;
+
+ fill(&s, 0);
+
+ for(;;)
+ {
+ s.tok = s.cur;
+/*!re2c
+ re2c:indent:top = 2;
+
+ NL = "\r"? "\n" ;
+ ANY = [^] ;
+
+ "/" "/" { goto cppcomment; }
+ "/" "*" { goto comment; }
+ ANY { fputc(*s.tok, stdout); continue; }
+*/
+comment:
+ s.tok = s.cur;
+/*!re2c
+ "*" "/" { continue; }
+ ANY { goto comment; }
+*/
+cppcomment:
+ s.tok = s.cur;
+/*!re2c
+ NL { fwrite(s.tok, 1, s.cur - s.tok, stdout); continue; }
+ ANY { goto cppcomment; }
+*/
+ }
+
+ if (fp != stdin)
+ {
+ fclose(fp); /* close only if not stdin */
+ }
+ return res; /* return result */
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ {
+ return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
+ }
+ else
+ {
+ fprintf(stderr, "%s <expr>\n", argv[0]);
+ return 1;
+ }
+}
--- /dev/null
+/* Generated by re2c */
+#line 1 "strip_002.s.re"
+/* re2c lesson_002, strip_002.s, (c) M. Boerger 2006 */
+#line 27 "strip_002.s.re"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define YYMAXFILL 4
+#define BSIZE 128
+
+#if BSIZE < YYMAXFILL
+# error BSIZE must be greater YYMAXFILL
+#endif
+
+#define YYCTYPE char
+#define YYCURSOR s.cur
+#define YYLIMIT s.lim
+#define YYMARKER s.mrk
+#define YYCTXMARKER s.ctx
+#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
+
+typedef struct Scanner
+{
+ FILE *fp;
+ char *cur, *tok, *lim, *eof, *ctx, *mrk;
+ char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->tok = s->cur = s->lim = s->mrk = 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;
+ s->mrk -= cnt;
+ s->ctx -= 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;
+}
+
+void echo(Scanner *s)
+{
+ fwrite(s->tok, 1, s->cur - s->tok, stdout);
+}
+
+int scan(FILE *fp)
+{
+ int res = 0;
+ int nlcomment = 0;
+ Scanner s;
+
+ if (!fp)
+ {
+ return 1; /* no file was opened */
+ }
+
+ s.fp = fp;
+
+ fill(&s, 0);
+
+ for(;;)
+ {
+ s.tok = s.cur;
+
+#line 90 "<stdout>"
+ {
+ YYCTYPE yych;
+
+ if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ if(yych <= 0x0C) {
+ if(yych == 0x0A) goto yy5;
+ goto yy6;
+ } else {
+ if(yych <= 0x0D) goto yy4;
+ if(yych != '/') goto yy6;
+ }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '*') goto yy12;
+ if(yych == '/') goto yy14;
+yy3:
+#line 120 "strip_002.s.re"
+ { fputc(*s.tok, stdout); continue; }
+#line 109 "<stdout>"
+yy4:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == 0x0A) goto yy11;
+ goto yy3;
+yy5:
+ YYCTXMARKER = YYCURSOR + 1;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == '/') goto yy7;
+ goto yy3;
+yy6:
+ yych = *++YYCURSOR;
+ goto yy3;
+yy7:
+ yych = *++YYCURSOR;
+ if(yych == '*') goto yy9;
+yy8:
+ YYCURSOR = YYMARKER;
+ goto yy3;
+yy9:
+ ++YYCURSOR;
+ YYCURSOR = YYCTXMARKER;
+#line 118 "strip_002.s.re"
+ { echo(&s); nlcomment = 1; continue; }
+#line 133 "<stdout>"
+yy11:
+ YYCTXMARKER = YYCURSOR + 1;
+ yych = *++YYCURSOR;
+ if(yych == '/') goto yy7;
+ goto yy8;
+yy12:
+ ++YYCURSOR;
+#line 119 "strip_002.s.re"
+ { goto comment; }
+#line 143 "<stdout>"
+yy14:
+ ++YYCURSOR;
+#line 117 "strip_002.s.re"
+ { goto cppcomment; }
+#line 148 "<stdout>"
+ }
+#line 121 "strip_002.s.re"
+
+comment:
+ s.tok = s.cur;
+
+#line 155 "<stdout>"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych != '*') goto yy20;
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '/') goto yy21;
+yy19:
+#line 126 "strip_002.s.re"
+ { goto comment; }
+#line 166 "<stdout>"
+yy20:
+ yych = *++YYCURSOR;
+ goto yy19;
+yy21:
+ ++YYCURSOR;
+#line 125 "strip_002.s.re"
+ { goto commentws; }
+#line 174 "<stdout>"
+ }
+#line 127 "strip_002.s.re"
+
+commentws:
+ s.tok = s.cur;
+
+#line 181 "<stdout>"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ if(yych <= 0x0D) {
+ if(yych <= 0x09) {
+ if(yych <= 0x08) goto yy32;
+ goto yy31;
+ } else {
+ if(yych <= 0x0A) goto yy27;
+ if(yych <= 0x0C) goto yy32;
+ }
+ } else {
+ if(yych <= ' ') {
+ if(yych <= 0x1F) goto yy32;
+ goto yy31;
+ } else {
+ if(yych == '/') goto yy29;
+ goto yy32;
+ }
+ }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == 0x0A) goto yy37;
+yy26:
+#line 140 "strip_002.s.re"
+ { goto commentws; }
+#line 208 "<stdout>"
+yy27:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == '/') goto yy35;
+yy28:
+#line 132 "strip_002.s.re"
+ {
+ if (!nlcomment)
+ {
+ echo(&s);
+ }
+ nlcomment = 0;
+ continue;
+ }
+#line 222 "<stdout>"
+yy29:
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '*') goto yy33;
+yy30:
+#line 141 "strip_002.s.re"
+ { echo(&s); nlcomment = 0; continue; }
+#line 229 "<stdout>"
+yy31:
+ yych = *++YYCURSOR;
+ goto yy26;
+yy32:
+ yych = *++YYCURSOR;
+ goto yy30;
+yy33:
+ ++YYCURSOR;
+#line 131 "strip_002.s.re"
+ { goto comment; }
+#line 240 "<stdout>"
+yy35:
+ yych = *++YYCURSOR;
+ if(yych == '*') goto yy33;
+ YYCURSOR = YYMARKER;
+ goto yy28;
+yy37:
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == '/') goto yy35;
+ goto yy28;
+ }
+#line 142 "strip_002.s.re"
+
+cppcomment:
+ s.tok = s.cur;
+
+#line 256 "<stdout>"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy42;
+ if(yych != 0x0D) goto yy44;
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == 0x0A) goto yy45;
+yy41:
+#line 147 "strip_002.s.re"
+ { goto cppcomment; }
+#line 268 "<stdout>"
+yy42:
+ ++YYCURSOR;
+yy43:
+#line 146 "strip_002.s.re"
+ { echo(&s); continue; }
+#line 274 "<stdout>"
+yy44:
+ yych = *++YYCURSOR;
+ goto yy41;
+yy45:
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy43;
+ }
+#line 148 "strip_002.s.re"
+
+ }
+
+ if (fp != stdin)
+ {
+ fclose(fp); /* close only if not stdin */
+ }
+ return res; /* return result */
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ {
+ return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
+ }
+ else
+ {
+ fprintf(stderr, "%s <expr>\n", argv[0]);
+ return 1;
+ }
+}
--- /dev/null
+/* re2c lesson_002, strip_002.s, (c) M. Boerger 2006 */
+/*!ignore:re2c
+
+- complexity
+ . When two comments are only separated by whitespace we want to drop both.
+ . When a comemnt is preceeded by a new line and followed by whitespace and a
+ new line then we can drop the trailing whitespace and new line.
+ But we cannot simply use the following two rules:
+ "*" "/" WS* "/" "*" { continue; }
+ "*" "/" WS* NL { continue; }
+ The main problem is that WS* can get bigger then our buffer, so we need a
+ new scanner.
+ . Meanwhile our scanner gets a bit more complex and we have to add two more
+ things. First the scanner code now uses a YYMARKER to store backtracking
+ information. And second we have a new rule that utilizes trailing contexts.
+ Therefore we also need to add YYCTXMARKER.
+- formatting
+ . Until now we only used single line expression code and we always had the
+ opening { on the same line as the rule itself. If we have multiline rule
+ code and care for formatting we can nolonger rely on re2c. Now we have
+ to indent the rule code ourself. Also we need to take care of the opening
+ {. If we keep it on the same line as the rule then re2c will indent it
+ correctly and the emitted #line informations will be correct. If we place
+ it on the next line then the #line directivy will also point to that line
+ and not to the rule.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*!max:re2c */
+#define BSIZE 128
+
+#if BSIZE < YYMAXFILL
+# error BSIZE must be greater YYMAXFILL
+#endif
+
+#define YYCTYPE char
+#define YYCURSOR s.cur
+#define YYLIMIT s.lim
+#define YYMARKER s.mrk
+#define YYCTXMARKER s.ctx
+#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
+
+typedef struct Scanner
+{
+ FILE *fp;
+ char *cur, *tok, *lim, *eof, *ctx, *mrk;
+ char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->tok = s->cur = s->lim = s->mrk = 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;
+ s->mrk -= cnt;
+ s->ctx -= 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;
+}
+
+void echo(Scanner *s)
+{
+ fwrite(s->tok, 1, s->cur - s->tok, stdout);
+}
+
+int scan(FILE *fp)
+{
+ int res = 0;
+ int nlcomment = 0;
+ Scanner s;
+
+ if (!fp)
+ {
+ return 1; /* no file was opened */
+ }
+
+ s.fp = fp;
+
+ fill(&s, 0);
+
+ for(;;)
+ {
+ s.tok = s.cur;
+/*!re2c
+ re2c:indent:top = 2;
+
+ NL = "\r"? "\n" ;
+ WS = [\r\n\t ] ;
+ ANY = [^] ;
+
+ "/" "/" { goto cppcomment; }
+ NL / "/""*" { echo(&s); nlcomment = 1; continue; }
+ "/" "*" { goto comment; }
+ ANY { fputc(*s.tok, stdout); continue; }
+*/
+comment:
+ s.tok = s.cur;
+/*!re2c
+ "*" "/" { goto commentws; }
+ ANY { goto comment; }
+*/
+commentws:
+ s.tok = s.cur;
+/*!re2c
+ NL? "/" "*" { goto comment; }
+ NL {
+ if (!nlcomment)
+ {
+ echo(&s);
+ }
+ nlcomment = 0;
+ continue;
+ }
+ WS { goto commentws; }
+ ANY { echo(&s); nlcomment = 0; continue; }
+*/
+cppcomment:
+ s.tok = s.cur;
+/*!re2c
+ NL { echo(&s); continue; }
+ ANY { goto cppcomment; }
+*/
+ }
+
+ if (fp != stdin)
+ {
+ fclose(fp); /* close only if not stdin */
+ }
+ return res; /* return result */
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ {
+ return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
+ }
+ else
+ {
+ fprintf(stderr, "%s <expr>\n", argv[0]);
+ return 1;
+ }
+}
--- /dev/null
+/* Generated by re2c 0.10.2.dev on Sun Apr 16 21:50:17 2006 */
+#line 1 "strip_002.s.re"
+/* re2c lesson_002, strip_001.s, (c) M. Boerger 2006 */
+#line 14 "strip_002.s.re"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define YYMAXFILL 4
+#define BSIZE 128
+
+#if BSIZE < YYMAXFILL
+# error BSIZE must be greater YYMAXFILL
+#endif
+
+#define YYCTYPE char
+#define YYCURSOR s.cur
+#define YYLIMIT s.lim
+#define YYMARKER s.mrk
+#define YYCTXMARKER s.ctx
+#define YYFILL(n) { if ((res = fill(&s, n)) >= 0) break; }
+
+typedef struct Scanner
+{
+ FILE *fp;
+ char *cur, *tok, *lim, *eof, *ctx, *mrk;
+ char buffer[BSIZE];
+} Scanner;
+
+int fill(Scanner *s, int len)
+{
+ if (!len)
+ {
+ s->tok = s->cur = s->lim = s->mrk = 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;
+ s->mrk -= cnt;
+ s->ctx -= 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;
+}
+
+void echo(Scanner *s)
+{
+ fwrite(s->tok, 1, s->cur - s->tok, stdout);
+}
+
+int scan(FILE *fp)
+{
+ int res = 0;
+ int nlcomment = 0;
+ Scanner s;
+
+ if (!fp)
+ {
+ return 1; // no file was opened
+ }
+
+ s.fp = fp;
+
+ fill(&s, 0);
+
+ for(;;)
+ {
+ s.tok = s.cur;
+
+#line 90 "t.c"
+ {
+ YYCTYPE yych;
+
+ if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ switch(yych){
+ case 0x0A: goto yy5;
+ case 0x0D: goto yy4;
+ case '/': goto yy2;
+ default: goto yy6;
+ }
+yy2:
+ ++YYCURSOR;
+ switch((yych = *YYCURSOR)) {
+ case '*': goto yy12;
+ case '/': goto yy14;
+ default: goto yy3;
+ }
+yy3:
+#line 107 "strip_002.s.re"
+ { fputc(*s.tok, stdout); continue; }
+#line 112 "t.c"
+yy4:
+ yych = *(YYMARKER = ++YYCURSOR);
+ switch(yych){
+ case 0x0A: goto yy11;
+ default: goto yy3;
+ }
+yy5:
+ YYCTXMARKER = YYCURSOR + 1;
+ yych = *(YYMARKER = ++YYCURSOR);
+ switch(yych){
+ case '/': goto yy7;
+ default: goto yy3;
+ }
+yy6:
+ yych = *++YYCURSOR;
+ goto yy3;
+yy7:
+ yych = *++YYCURSOR;
+ switch(yych){
+ case '*': goto yy9;
+ default: goto yy8;
+ }
+yy8:
+ YYCURSOR = YYMARKER;
+ goto yy3;
+yy9:
+ ++YYCURSOR;
+ YYCURSOR = YYCTXMARKER;
+#line 105 "strip_002.s.re"
+ { echo(&s); nlcomment = 1; continue; }
+#line 143 "t.c"
+yy11:
+ YYCTXMARKER = YYCURSOR + 1;
+ yych = *++YYCURSOR;
+ switch(yych){
+ case '/': goto yy7;
+ default: goto yy8;
+ }
+yy12:
+ ++YYCURSOR;
+#line 106 "strip_002.s.re"
+ { goto comment; }
+#line 155 "t.c"
+yy14:
+ ++YYCURSOR;
+#line 104 "strip_002.s.re"
+ { goto cppcomment; }
+#line 160 "t.c"
+ }
+#line 108 "strip_002.s.re"
+
+comment:
+ s.tok = s.cur;
+
+#line 167 "t.c"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ switch(yych){
+ case '*': goto yy18;
+ default: goto yy20;
+ }
+yy18:
+ ++YYCURSOR;
+ switch((yych = *YYCURSOR)) {
+ case '/': goto yy21;
+ default: goto yy19;
+ }
+yy19:
+#line 113 "strip_002.s.re"
+ { goto comment; }
+#line 185 "t.c"
+yy20:
+ yych = *++YYCURSOR;
+ goto yy19;
+yy21:
+ ++YYCURSOR;
+#line 112 "strip_002.s.re"
+ { goto commentws; }
+#line 193 "t.c"
+ }
+#line 114 "strip_002.s.re"
+
+commentws:
+ s.tok = s.cur;
+
+#line 200 "t.c"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ switch(yych){
+ case 0x09:
+ case ' ': goto yy31;
+ case 0x0A: goto yy27;
+ case 0x0D: goto yy25;
+ case '/': goto yy29;
+ default: goto yy32;
+ }
+yy25:
+ ++YYCURSOR;
+ switch((yych = *YYCURSOR)) {
+ case 0x0A: goto yy37;
+ default: goto yy26;
+ }
+yy26:
+#line 127 "strip_002.s.re"
+ { goto commentws; }
+#line 222 "t.c"
+yy27:
+ yych = *(YYMARKER = ++YYCURSOR);
+ switch(yych){
+ case '/': goto yy35;
+ default: goto yy28;
+ }
+yy28:
+#line 119 "strip_002.s.re"
+ {
+ if (!nlcomment)
+ {
+ echo(&s);
+ }
+ nlcomment = 0;
+ continue;
+ }
+#line 239 "t.c"
+yy29:
+ ++YYCURSOR;
+ switch((yych = *YYCURSOR)) {
+ case '*': goto yy33;
+ default: goto yy30;
+ }
+yy30:
+#line 128 "strip_002.s.re"
+ { echo(&s); nlcomment = 0; continue; }
+#line 249 "t.c"
+yy31:
+ yych = *++YYCURSOR;
+ goto yy26;
+yy32:
+ yych = *++YYCURSOR;
+ goto yy30;
+yy33:
+ ++YYCURSOR;
+#line 118 "strip_002.s.re"
+ { nlcomment = 1; goto comment; }
+#line 260 "t.c"
+yy35:
+ yych = *++YYCURSOR;
+ switch(yych){
+ case '*': goto yy33;
+ default: goto yy36;
+ }
+yy36:
+ YYCURSOR = YYMARKER;
+ goto yy28;
+yy37:
+ yych = *(YYMARKER = ++YYCURSOR);
+ switch(yych){
+ case '/': goto yy35;
+ default: goto yy28;
+ }
+ }
+#line 129 "strip_002.s.re"
+
+cppcomment:
+ s.tok = s.cur;
+
+#line 282 "t.c"
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ switch(yych){
+ case 0x0A: goto yy42;
+ case 0x0D: goto yy40;
+ default: goto yy44;
+ }
+yy40:
+ ++YYCURSOR;
+ switch((yych = *YYCURSOR)) {
+ case 0x0A: goto yy45;
+ default: goto yy41;
+ }
+yy41:
+#line 134 "strip_002.s.re"
+ { goto cppcomment; }
+#line 301 "t.c"
+yy42:
+ ++YYCURSOR;
+yy43:
+#line 133 "strip_002.s.re"
+ { echo(&s); continue; }
+#line 307 "t.c"
+yy44:
+ yych = *++YYCURSOR;
+ goto yy41;
+yy45:
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy43;
+ }
+#line 135 "strip_002.s.re"
+
+ }
+
+ fflush(fp); // ensure we write
+ if (fp != stdin)
+ {
+ fclose(fp); // close only if not stdin
+ }
+ return res; // return result
+}
+
+/**/
+/**/
+/***/
+/***/
+/****/
+/****/
+/*****/
+/*****/
+/******/
+/******/
+
+int main(int argc, char **argv)
+{
+ if (argc > 1)
+ {
+ return scan(!strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r"));
+ }
+ else
+ {
+ fprintf(stderr, "%s <expr>\n", argv[0]);
+ return 1;
+ }
+}