From: helly Date: Sun, 25 Feb 2007 17:15:14 +0000 (+0000) Subject: - Extend lesson 1 X-Git-Tag: 0.13.6~224 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=618b1ce40af496f8be76de50140244d9cca46f5c;p=re2c - Extend lesson 1 --- 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 index 00000000..491ea888 --- /dev/null +++ b/re2c/lessons/001_upn_calculator/calc_008.b.c @@ -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 +#include +#include + +#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 "" + { + 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 "" +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 "" +scan6: + curr = (unsigned char)*++p; + goto scan16; +scan7: + ++p; +#line 106 "calc_008.b.re" + { res = stack_add(); continue; } +#line 146 "" +scan9: + ++p; +#line 107 "calc_008.b.re" + { res = stack_sub(); continue; } +#line 151 "" +scan11: + ++p; +#line 108 "calc_008.b.re" + { res = depth == 1 ? 0 : 2; break; } +#line 156 "" +scan13: + ++p; +#line 109 "calc_008.b.re" + { res = 1; continue; } +#line 161 "" +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 "" +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 \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 index 00000000..ed1a088e --- /dev/null +++ b/re2c/lessons/001_upn_calculator/calc_008.b.re @@ -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 +#include +#include + +#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 \n", argv[0]); + return 0; + } +}