]> granicus.if.org Git - re2c/commitdiff
- Update lesson 2 and split YYMARKER/YYCTXMARKER stuff in two steps
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 17 Apr 2006 15:03:53 +0000 (15:03 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Mon, 17 Apr 2006 15:03:53 +0000 (15:03 +0000)
lessons/002_strip_comments/.cvsignore
lessons/002_strip_comments/readme.txt
lessons/002_strip_comments/strip_002.s.c
lessons/002_strip_comments/strip_002.s.re
lessons/002_strip_comments/strip_003.b.c [new file with mode: 0755]
lessons/002_strip_comments/strip_003.b.re [new file with mode: 0755]

index 1938665bef07d0dad890c8d22ffb0fa57ccf546b..eb177879673ce71eabbc8bcf280a6656b67bfe03 100755 (executable)
@@ -2,3 +2,4 @@ a.out
 *.temp
 *.diff
 *.o
+t.c
index 9805d20b77fdc425f1da27015c9430f9a260e70a..353d6690418d71cf5a473681d324ce25a04e58b5 100755 (executable)
@@ -10,4 +10,12 @@ 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.
+information.
+
+  re2c -s -0 t.c strip_002.b.re
+
+The third step brings trailing contexts that are stored in YYCTXMARKER. We also
+change to use -b instead of -s option since the scanner gets more and more
+complex.
+
+  re2c -b -0 t.c strip_002.b.re
index b87912cf60fe7a51353264892f0980de26fc81c0..be5cff400945d21f51fd1edb898fd517397b220c 100755 (executable)
@@ -1,13 +1,13 @@
 /* Generated by re2c */
 #line 1 "strip_002.s.re"
 /* re2c lesson 002_strip_comments, strip_002.s, (c) M. Boerger 2006 */
-#line 27 "strip_002.s.re"
+#line 34 "strip_002.s.re"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
-#define YYMAXFILL 4
+#define YYMAXFILL 2
 #define        BSIZE   128
 
 #if BSIZE < YYMAXFILL
 #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            *cur, *tok, *lim, *eof, *mrk;
        char            buffer[BSIZE];
 } Scanner;
 
@@ -46,7 +45,6 @@ int fill(Scanner *s, int len)
                        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)
@@ -86,130 +84,91 @@ int scan(FILE *fp)
        {
                s.tok = s.cur;
 
-#line 90 "<stdout>"
+#line 88 "<stdout>"
                {
                        YYCTYPE yych;
 
-                       if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+                       if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                        yych = *YYCURSOR;
-                       if(yych <= 0x0C) {
-                               if(yych == 0x0A) goto yy5;
-                               goto yy6;
-                       } else {
-                               if(yych <= 0x0D) goto yy4;
-                               if(yych != '/') goto yy6;
-                       }
+                       if(yych != '/') goto yy4;
                        ++YYCURSOR;
-                       if((yych = *YYCURSOR) == '*') goto yy12;
-                       if(yych == '/') goto yy14;
+                       if((yych = *YYCURSOR) == '*') goto yy5;
+                       if(yych == '/') goto yy7;
 yy3:
-#line 120 "strip_002.s.re"
+#line 124 "strip_002.s.re"
                        { fputc(*s.tok, stdout); continue; }
-#line 109 "<stdout>"
+#line 101 "<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:
+yy5:
                        ++YYCURSOR;
-#line 119 "strip_002.s.re"
+#line 123 "strip_002.s.re"
                        { goto comment; }
-#line 143 "<stdout>"
-yy14:
+#line 109 "<stdout>"
+yy7:
                        ++YYCURSOR;
-#line 117 "strip_002.s.re"
+#line 122 "strip_002.s.re"
                        { goto cppcomment; }
-#line 148 "<stdout>"
+#line 114 "<stdout>"
                }
-#line 121 "strip_002.s.re"
+#line 125 "strip_002.s.re"
 
 comment:
                s.tok = s.cur;
 
-#line 155 "<stdout>"
+#line 121 "<stdout>"
                {
                        YYCTYPE yych;
                        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                        yych = *YYCURSOR;
-                       if(yych != '*') goto yy20;
+                       if(yych != '*') goto yy13;
                        ++YYCURSOR;
-                       if((yych = *YYCURSOR) == '/') goto yy21;
-yy19:
-#line 126 "strip_002.s.re"
+                       if((yych = *YYCURSOR) == '/') goto yy14;
+yy12:
+#line 130 "strip_002.s.re"
                        { goto comment; }
-#line 166 "<stdout>"
-yy20:
+#line 132 "<stdout>"
+yy13:
                        yych = *++YYCURSOR;
-                       goto yy19;
-yy21:
+                       goto yy12;
+yy14:
                        ++YYCURSOR;
-#line 125 "strip_002.s.re"
+#line 129 "strip_002.s.re"
                        { goto commentws; }
-#line 174 "<stdout>"
+#line 140 "<stdout>"
                }
-#line 127 "strip_002.s.re"
+#line 131 "strip_002.s.re"
 
 commentws:
                s.tok = s.cur;
 
-#line 181 "<stdout>"
+#line 147 "<stdout>"
                {
                        YYCTYPE yych;
-                       if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+                       if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                        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;
-                               }
+                       if(yych <= 0x0C) {
+                               if(yych <= 0x08) goto yy23;
+                               if(yych <= 0x09) goto yy22;
+                               if(yych <= 0x0A) goto yy20;
+                               goto yy23;
                        } else {
-                               if(yych <= ' ') {
-                                       if(yych <= 0x1F) goto yy32;
-                                       goto yy31;
-                               } else {
-                                       if(yych == '/') goto yy29;
-                                       goto yy32;
-                               }
+                               if(yych <= 0x0D) goto yy18;
+                               if(yych == ' ') goto yy22;
+                               goto yy23;
                        }
+yy18:
                        ++YYCURSOR;
-                       if((yych = *YYCURSOR) == 0x0A) goto yy37;
-yy26:
-#line 140 "strip_002.s.re"
+                       if((yych = *YYCURSOR) == 0x0A) goto yy25;
+yy19:
+#line 143 "strip_002.s.re"
                        { goto commentws; }
-#line 208 "<stdout>"
-yy27:
-                       yych = *(YYMARKER = ++YYCURSOR);
-                       if(yych == '/') goto yy35;
-yy28:
-#line 132 "strip_002.s.re"
+#line 168 "<stdout>"
+yy20:
+                       ++YYCURSOR;
+yy21:
+#line 135 "strip_002.s.re"
                        {
                                if (!nlcomment)
                                {
@@ -218,68 +177,53 @@ yy28:
                                nlcomment = 0;
                                continue;
                        }
-#line 222 "<stdout>"
-yy29:
+#line 181 "<stdout>"
+yy22:
+                       yych = *++YYCURSOR;
+                       goto yy19;
+yy23:
                        ++YYCURSOR;
-                       if((yych = *YYCURSOR) == '*') goto yy33;
-yy30:
-#line 141 "strip_002.s.re"
+#line 144 "strip_002.s.re"
                        { echo(&s); nlcomment = 0; continue; }
-#line 229 "<stdout>"
-yy31:
-                       yych = *++YYCURSOR;
-                       goto yy26;
-yy32:
-                       yych = *++YYCURSOR;
-                       goto yy30;
-yy33:
+#line 189 "<stdout>"
+yy25:
                        ++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;
+                       yych = *YYCURSOR;
+                       goto yy21;
                }
-#line 142 "strip_002.s.re"
+#line 145 "strip_002.s.re"
 
 cppcomment:
                s.tok = s.cur;
 
-#line 256 "<stdout>"
+#line 200 "<stdout>"
                {
                        YYCTYPE yych;
                        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
                        yych = *YYCURSOR;
-                       if(yych == 0x0A) goto yy42;
-                       if(yych != 0x0D) goto yy44;
+                       if(yych == 0x0A) goto yy30;
+                       if(yych != 0x0D) goto yy32;
                        ++YYCURSOR;
-                       if((yych = *YYCURSOR) == 0x0A) goto yy45;
-yy41:
-#line 147 "strip_002.s.re"
+                       if((yych = *YYCURSOR) == 0x0A) goto yy33;
+yy29:
+#line 150 "strip_002.s.re"
                        { goto cppcomment; }
-#line 268 "<stdout>"
-yy42:
+#line 212 "<stdout>"
+yy30:
                        ++YYCURSOR;
-yy43:
-#line 146 "strip_002.s.re"
+yy31:
+#line 149 "strip_002.s.re"
                        { echo(&s); continue; }
-#line 274 "<stdout>"
-yy44:
+#line 218 "<stdout>"
+yy32:
                        yych = *++YYCURSOR;
-                       goto yy41;
-yy45:
+                       goto yy29;
+yy33:
                        ++YYCURSOR;
                        yych = *YYCURSOR;
-                       goto yy43;
+                       goto yy31;
                }
-#line 148 "strip_002.s.re"
+#line 151 "strip_002.s.re"
 
        }
 
index 9422005fe239f5f82ce87e1c226b89401054135e..b440a6b40b4f36b8f3be3939d9c86ddf762caf0c 100755 (executable)
@@ -2,7 +2,6 @@
 /*!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:
        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.
+    information.
+
+- backtracking information
+  . When the scanner has two rules that can have the same beginning but a 
+    different ending then it needs to store the position that identifies the
+    common part. This is called backtracking. As mentioned above re2c expects
+    you to provide compiler define YYMARKER and a pointer variable.
+  . When shifting buffer contents as done in our fill function the marker needs
+    to be corrected, too.
+
 - 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
 #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            *cur, *tok, *lim, *eof, *mrk;
        char            buffer[BSIZE];
 } Scanner;
 
@@ -68,7 +74,6 @@ int fill(Scanner *s, int len)
                        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)
@@ -115,7 +120,6 @@ int scan(FILE *fp)
        ANY                     = [^] ;
 
        "/" "/"         { goto cppcomment; }
-       NL / "/""*"     { echo(&s); nlcomment = 1; continue; }
        "/" "*"         { goto comment; }
        ANY                     { fputc(*s.tok, stdout); continue; }
 */
@@ -128,7 +132,6 @@ comment:
 commentws:
                s.tok = s.cur;
 /*!re2c
-       NL? "/" "*"     { goto comment; }
        NL                      {
                                if (!nlcomment)
                                {
diff --git a/lessons/002_strip_comments/strip_003.b.c b/lessons/002_strip_comments/strip_003.b.c
new file mode 100755 (executable)
index 0000000..8de0bf3
--- /dev/null
@@ -0,0 +1,312 @@
+/* Generated by re2c */
+#line 1 "strip_003.b.re"
+/* re2c lesson 002_strip_comments, strip_003.b, (c) M. Boerger 2006 */
+#line 29 "strip_003.b.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 91 "<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 122 "strip_003.b.re"
+                               { fputc(*s.tok, stdout); continue; }
+#line 110 "<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 120 "strip_003.b.re"
+                               { echo(&s); nlcomment = 1; continue; }
+#line 134 "<stdout>"
+yy11:
+                               YYCTXMARKER = YYCURSOR + 1;
+                               yych = *++YYCURSOR;
+                               if(yych == '/') goto yy7;
+                               goto yy8;
+yy12:
+                               ++YYCURSOR;
+#line 121 "strip_003.b.re"
+                               { goto comment; }
+#line 144 "<stdout>"
+yy14:
+                               ++YYCURSOR;
+#line 119 "strip_003.b.re"
+                               { goto cppcomment; }
+#line 149 "<stdout>"
+                       }
+               }
+#line 123 "strip_003.b.re"
+
+comment:
+               s.tok = s.cur;
+               {
+
+#line 158 "<stdout>"
+                       {
+                               YYCTYPE yych;
+                               if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+                               yych = *YYCURSOR;
+                               if(yych != '*') goto yy20;
+                               ++YYCURSOR;
+                               if((yych = *YYCURSOR) == '/') goto yy21;
+yy19:
+#line 128 "strip_003.b.re"
+                               { goto comment; }
+#line 169 "<stdout>"
+yy20:
+                               yych = *++YYCURSOR;
+                               goto yy19;
+yy21:
+                               ++YYCURSOR;
+#line 127 "strip_003.b.re"
+                               { goto commentws; }
+#line 177 "<stdout>"
+                       }
+               }
+#line 129 "strip_003.b.re"
+
+commentws:
+               s.tok = s.cur;
+               {
+
+#line 186 "<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 142 "strip_003.b.re"
+                               { goto commentws; }
+#line 213 "<stdout>"
+yy27:
+                               yych = *(YYMARKER = ++YYCURSOR);
+                               if(yych == '/') goto yy35;
+yy28:
+#line 134 "strip_003.b.re"
+                               {
+                               if (!nlcomment)
+                               {
+                                       echo(&s);
+                               }
+                               nlcomment = 0;
+                               continue;
+                       }
+#line 227 "<stdout>"
+yy29:
+                               ++YYCURSOR;
+                               if((yych = *YYCURSOR) == '*') goto yy33;
+yy30:
+#line 143 "strip_003.b.re"
+                               { echo(&s); nlcomment = 0; continue; }
+#line 234 "<stdout>"
+yy31:
+                               yych = *++YYCURSOR;
+                               goto yy26;
+yy32:
+                               yych = *++YYCURSOR;
+                               goto yy30;
+yy33:
+                               ++YYCURSOR;
+#line 133 "strip_003.b.re"
+                               { goto comment; }
+#line 245 "<stdout>"
+yy35:
+                               yych = *++YYCURSOR;
+                               if(yych == '*') goto yy33;
+                               YYCURSOR = YYMARKER;
+                               goto yy28;
+yy37:
+                               yych = *(YYMARKER = ++YYCURSOR);
+                               if(yych == '/') goto yy35;
+                               goto yy28;
+                       }
+               }
+#line 144 "strip_003.b.re"
+
+cppcomment:
+               s.tok = s.cur;
+               {
+
+#line 263 "<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 149 "strip_003.b.re"
+                               { goto cppcomment; }
+#line 275 "<stdout>"
+yy42:
+                               ++YYCURSOR;
+yy43:
+#line 148 "strip_003.b.re"
+                               { echo(&s); continue; }
+#line 281 "<stdout>"
+yy44:
+                               yych = *++YYCURSOR;
+                               goto yy41;
+yy45:
+                               ++YYCURSOR;
+                               yych = *YYCURSOR;
+                               goto yy43;
+                       }
+               }
+#line 150 "strip_003.b.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;
+       }
+}
diff --git a/lessons/002_strip_comments/strip_003.b.re b/lessons/002_strip_comments/strip_003.b.re
new file mode 100755 (executable)
index 0000000..41db8f2
--- /dev/null
@@ -0,0 +1,171 @@
+/* re2c lesson 002_strip_comments, strip_003.b, (c) M. Boerger 2006 */
+/*!ignore:re2c
+
+- more complexity
+  . Additional to what we strip out already what about two consequtive comment 
+    blocks? When two comments are only separated by whitespace we want to drop 
+    both. In other words when detecting the end of a comment block we need to 
+    check whether it is followed by only whitespace and the a new comment in
+    which case we continure ignoring the input. If it is followed only by white
+    space and a new line we strip out the new white space and new line. In any
+    other case we start outputting all that follows.
+  . The solution to the above is to use trailing contexts.
+
+-  trailing contexts
+  . Re2c allows to check for a portion of input and only recognize it when it 
+    is followed by another portion. This is called a trailing context.
+  . The trailing context is not part of the identified input. That means that
+    it follows exactly at the cursor. A consequence is that the scanner has
+    already read more input and on the next run you need to restore begining
+    of input, in our case s.tok, from the cursor, here s.cur, rather then 
+    restoring to the beginning of the buffer. This way the scanner can reuse
+    the portion it has already read.
+  . The position of the trailing context is stored in YYCTXMARKER for which
+    a pointer variable needs to be provided.
+  . As with YYMARKER the corrsponding variable needs to be corrected if we 
+    shift in some buffer.
+
+*/
+
+#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;
+       }
+}