]> granicus.if.org Git - re2c/commitdiff
- Extend lesson 1
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 25 Feb 2007 17:15:14 +0000 (17:15 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 25 Feb 2007 17:15:14 +0000 (17:15 +0000)
re2c/lessons/001_upn_calculator/calc_008.b.c [new file with mode: 0755]
re2c/lessons/001_upn_calculator/calc_008.b.re [new file with mode: 0755]

diff --git a/re2c/lessons/001_upn_calculator/calc_008.b.c b/re2c/lessons/001_upn_calculator/calc_008.b.c
new file mode 100755 (executable)
index 0000000..491ea88
--- /dev/null
@@ -0,0 +1,237 @@
+/* Generated by re2c */
+#line 1 "calc_008.b.re"
+/* re2c lesson 001_upn_calculator, calc_008, (c) M. Boerger 2006 - 2007 */
+#line 31 "calc_008.b.re"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG(stmt) stmt
+
+int  stack[4];
+int  depth = 0;
+
+int push_num(const char *t, const char *l, int radix)
+{
+       int num = 0;
+       
+       if (depth >= sizeof(stack))
+       {
+               return 3;
+       }
+
+       --t;
+       while(++t < l)
+       {
+               num = num * radix + (*t - '0');
+       }
+       DEBUG(printf("Num: %d\n", num));
+
+       stack[depth++] = num;
+       return 0;
+}
+
+int stack_add()
+{
+       if (depth < 2) return 4;
+       
+       --depth;
+       stack[depth-1] = stack[depth-1] + stack[depth];
+       DEBUG(printf("+\n"));
+       return 0;
+}
+
+int stack_sub()
+{
+       if (depth < 2) return 4;
+
+       --depth;
+       stack[depth-1] = stack[depth-1] - stack[depth];
+       DEBUG(printf("+\n"));
+       return 0;
+}
+
+int scan(char *p)
+{
+       char *t;
+       int res = 0;
+       
+       while(!res)
+       {
+               t = p;
+               {
+                       static const unsigned char yybm[] = {
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0, 128,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                               128,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                64,  64,  64,  64,  64,  64,  64,  64, 
+                                64,  64,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                                 0,   0,   0,   0,   0,   0,   0,   0, 
+                       };
+
+#line 100 "<stdout>"
+                       {
+                               unsigned char curr;
+
+                               curr = (unsigned char)*p;
+                               if(curr <= '*') {
+                                       if(curr <= 0x09) {
+                                               if(curr <= 0x00) goto scan11;
+                                               if(curr <= 0x08) goto scan13;
+                                       } else {
+                                               if(curr != ' ') goto scan13;
+                                       }
+                               } else {
+                                       if(curr <= '-') {
+                                               if(curr <= '+') goto scan7;
+                                               if(curr <= ',') goto scan13;
+                                               goto scan9;
+                                       } else {
+                                               if(curr <= '/') goto scan13;
+                                               if(curr <= '0') goto scan4;
+                                               if(curr <= '9') goto scan6;
+                                               goto scan13;
+                                       }
+                               }
+                               ++p;
+                               curr = (unsigned char)*p;
+                               goto scan21;
+scan3:
+#line 103 "calc_008.b.re"
+                               { continue; }
+#line 130 "<stdout>"
+scan4:
+                               ++p;
+                               if((curr = (unsigned char)*p) <= '/') goto scan5;
+                               if(curr <= '9') goto scan17;
+scan5:
+#line 105 "calc_008.b.re"
+                               { res = push_num(t, p, 10); continue; }
+#line 138 "<stdout>"
+scan6:
+                               curr = (unsigned char)*++p;
+                               goto scan16;
+scan7:
+                               ++p;
+#line 106 "calc_008.b.re"
+                               { res = stack_add();            continue; }
+#line 146 "<stdout>"
+scan9:
+                               ++p;
+#line 107 "calc_008.b.re"
+                               { res = stack_sub();            continue; }
+#line 151 "<stdout>"
+scan11:
+                               ++p;
+#line 108 "calc_008.b.re"
+                               { res = depth == 1 ? 0 : 2;     break; }
+#line 156 "<stdout>"
+scan13:
+                               ++p;
+#line 109 "calc_008.b.re"
+                               { res = 1;                                      continue; }
+#line 161 "<stdout>"
+scan15:
+                               ++p;
+                               curr = (unsigned char)*p;
+scan16:
+                               if(yybm[0+curr] & 64) {
+                                       goto scan15;
+                               }
+                               goto scan5;
+scan17:
+                               ++p;
+                               curr = (unsigned char)*p;
+                               if(curr <= '/') goto scan19;
+                               if(curr <= '9') goto scan17;
+scan19:
+#line 104 "calc_008.b.re"
+                               { res = push_num(t, p, 8);      continue; }
+#line 178 "<stdout>"
+scan20:
+                               ++p;
+                               curr = (unsigned char)*p;
+scan21:
+                               if(yybm[0+curr] & 128) {
+                                       goto scan20;
+                               }
+                               goto scan3;
+                       }
+               }
+#line 110 "calc_008.b.re"
+
+       }
+       return res;
+}
+
+int main(int argc, char **argv)
+{
+       if (argc > 1)
+       {
+               char *inp;
+               int res = 0, argp = 0, len;
+               
+               while(!res && ++argp < argc)
+               {
+                       inp = strdup(argv[argp]);
+                       len = strlen(inp);
+                       if (inp[0] == '\"' && inp[len-1] == '\"')
+                       {
+                               inp[len - 1] = '\0';
+                               ++inp;
+                       }
+                       res = scan(inp);
+                       free(inp);
+               }
+               switch(res)
+               {
+               case 0:
+                       printf("Result: %d\n", stack[0]);
+                       return 0;
+               case 1:
+                       fprintf(stderr, "Illegal character in input.\n");
+                       return 1;
+               case 2:
+                       fprintf(stderr, "Premature end of input.\n");
+                       return 2;
+               case 3:
+                       fprintf(stderr, "Stack overflow.\n");
+                       return 3;
+               case 4:
+                       fprintf(stderr, "Stack underflow.\n");
+                       return 4;
+               }
+       }
+       else
+       {
+               fprintf(stderr, "%s <expr>\n", argv[0]);
+               return 0;
+       }
+}
diff --git a/re2c/lessons/001_upn_calculator/calc_008.b.re b/re2c/lessons/001_upn_calculator/calc_008.b.re
new file mode 100755 (executable)
index 0000000..ed1a088
--- /dev/null
@@ -0,0 +1,158 @@
+/* re2c lesson 001_upn_calculator, calc_008, (c) M. Boerger 2006 - 2007 */
+/*!ignore:re2c
+
+- using -b with signed character input
+  . Since the code is being generated with -b switch re2c requires the internal
+    character variable yych to use an unsigned character type. For that reason 
+    the previous lessons had a conversion at the beginning of their scan() 
+    function. Other re2c generated code often have the scanners work completely
+    on unsigned input. Thus requesting a conversion.
+    
+    To avoid the conversion on input, re2c allows to do the conversion when
+    reading the internal yych variable. To enable that conversion you need to
+    use the implace configuration 're2c:yych:conversion' and set it to 1. This
+    will change the generated code to insert conversions to YYCTYPE whenever
+    yych is being read.
+
+- More inplace configurations for better/nicer code
+  . re2c allows to overwrite the generation of any define, label or variable
+    used in the generated code. For example we overwrite the 'yych' variable
+    name to 'curr' using inplace configuration 're2c:variable:yych = curr;'.
+
+  . We further more use inplace configurations instead of defines. This allows
+    to use correct conversions to 'unsigned char' instead of having to convert
+    to 'YYCTYPE' when placing 're2c:define:YYCTYPE = "unsigned char";' infront 
+    of 're2c:yych:conversion'. Note that we have to use apostrophies for the
+    first setting as it contains a space.
+
+  . Last but not least we use 're2c:labelprefix = scan' to change the prefix
+    of generated labels.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define DEBUG(stmt) stmt
+
+int  stack[4];
+int  depth = 0;
+
+int push_num(const char *t, const char *l, int radix)
+{
+       int num = 0;
+       
+       if (depth >= sizeof(stack))
+       {
+               return 3;
+       }
+
+       --t;
+       while(++t < l)
+       {
+               num = num * radix + (*t - '0');
+       }
+       DEBUG(printf("Num: %d\n", num));
+
+       stack[depth++] = num;
+       return 0;
+}
+
+int stack_add()
+{
+       if (depth < 2) return 4;
+       
+       --depth;
+       stack[depth-1] = stack[depth-1] + stack[depth];
+       DEBUG(printf("+\n"));
+       return 0;
+}
+
+int stack_sub()
+{
+       if (depth < 2) return 4;
+
+       --depth;
+       stack[depth-1] = stack[depth-1] - stack[depth];
+       DEBUG(printf("+\n"));
+       return 0;
+}
+
+int scan(char *p)
+{
+       char *t;
+       int res = 0;
+       
+       while(!res)
+       {
+               t = p;
+/*!re2c
+       re2c:define:YYCTYPE  = "unsigned char";
+       re2c:define:YYCURSOR = p;
+       re2c:variable:yych   = curr;
+       re2c:indent:top      = 2;
+       re2c:yyfill:enable   = 0;
+       re2c:yych:conversion = 1;
+       re2c:labelprefix     = scan;
+
+       DIGIT   = [0-9] ;
+       OCT             = "0" DIGIT+ ;
+       INT             = "0" | ( [1-9] DIGIT* ) ;
+       WS              = [ \t]+ ;
+
+       WS              { continue; }
+       OCT             { res = push_num(t, p, 8);      continue; }
+       INT             { res = push_num(t, p, 10); continue; }
+       "+"             { res = stack_add();            continue; }
+       "-"             { res = stack_sub();            continue; }
+       "\000"  { res = depth == 1 ? 0 : 2;     break; }
+       [^]             { res = 1;                                      continue; }
+*/
+       }
+       return res;
+}
+
+int main(int argc, char **argv)
+{
+       if (argc > 1)
+       {
+               char *inp;
+               int res = 0, argp = 0, len;
+               
+               while(!res && ++argp < argc)
+               {
+                       inp = strdup(argv[argp]);
+                       len = strlen(inp);
+                       if (inp[0] == '\"' && inp[len-1] == '\"')
+                       {
+                               inp[len - 1] = '\0';
+                               ++inp;
+                       }
+                       res = scan(inp);
+                       free(inp);
+               }
+               switch(res)
+               {
+               case 0:
+                       printf("Result: %d\n", stack[0]);
+                       return 0;
+               case 1:
+                       fprintf(stderr, "Illegal character in input.\n");
+                       return 1;
+               case 2:
+                       fprintf(stderr, "Premature end of input.\n");
+                       return 2;
+               case 3:
+                       fprintf(stderr, "Stack overflow.\n");
+                       return 3;
+               case 4:
+                       fprintf(stderr, "Stack underflow.\n");
+                       return 4;
+               }
+       }
+       else
+       {
+               fprintf(stderr, "%s <expr>\n", argv[0]);
+               return 0;
+       }
+}