--- /dev/null
+/* 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;
+ }
+}
--- /dev/null
+/* 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;
+ }
+}