1 /* Generated by re2c */
2 #line 1 "calc_006.re"
3 // re2c $INPUT -o $OUTPUT -s
4 /* re2c lesson 001_upn_calculator, calc_006, (c) M. Boerger 2006 - 2007 */
5 #line 36 "calc_006.re"
6
7
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #define DEBUG(stmt) stmt
13
14 int stack[4];
15 int depth = 0;
16
push_num(const unsigned char * t,const unsigned char * l,int radix)17 int push_num(const unsigned char *t, const unsigned char *l, int radix)
18 {
19 int num = 0;
20
21 if (depth >= sizeof(stack))
22 {
23 return 3;
24 }
25
26 --t;
27 while(++t < l)
28 {
29 num = num * radix + (*t - (unsigned char)'0');
30 }
31 DEBUG(printf("Num: %d\n", num));
32
33 stack[depth++] = num;
34 return 0;
35 }
36
stack_add()37 int stack_add()
38 {
39 if (depth < 2) return 4;
40
41 --depth;
42 stack[depth-1] = stack[depth-1] + stack[depth];
43 DEBUG(printf("+\n"));
44 return 0;
45 }
46
stack_sub()47 int stack_sub()
48 {
49 if (depth < 2) return 4;
50
51 --depth;
52 stack[depth-1] = stack[depth-1] - stack[depth];
53 DEBUG(printf("-\n"));
54 return 0;
55 }
56
scan(char * s)57 int scan(char *s)
58 {
59 unsigned char *p = (unsigned char*)s;
60 unsigned char *t;
61 int res = 0;
62
63 #define YYCTYPE unsigned char
64 #define YYCURSOR p
65
66 while(!res)
67 {
68 t = p;
69
70 #line 71 "calc_006.c"
71 {
72 YYCTYPE yych;
73 yych = *YYCURSOR;
74 if (yych <= '*') {
75 if (yych <= '\t') {
76 if (yych <= 0x00) goto yy2;
77 if (yych <= 0x08) goto yy4;
78 goto yy6;
79 } else {
80 if (yych == ' ') goto yy6;
81 goto yy4;
82 }
83 } else {
84 if (yych <= '-') {
85 if (yych <= '+') goto yy9;
86 if (yych <= ',') goto yy4;
87 goto yy11;
88 } else {
89 if (yych <= '/') goto yy4;
90 if (yych <= '0') goto yy13;
91 if (yych <= '9') goto yy15;
92 goto yy4;
93 }
94 }
95 yy2:
96 ++YYCURSOR;
97 #line 113 "calc_006.re"
98 { res = depth == 1 ? 0 : 2; break; }
99 #line 100 "calc_006.c"
100 yy4:
101 ++YYCURSOR;
102 #line 114 "calc_006.re"
103 { res = 1; continue; }
104 #line 105 "calc_006.c"
105 yy6:
106 yych = *++YYCURSOR;
107 if (yych == '\t') goto yy6;
108 if (yych == ' ') goto yy6;
109 #line 108 "calc_006.re"
110 { continue; }
111 #line 112 "calc_006.c"
112 yy9:
113 ++YYCURSOR;
114 #line 111 "calc_006.re"
115 { res = stack_add(); continue; }
116 #line 117 "calc_006.c"
117 yy11:
118 ++YYCURSOR;
119 #line 112 "calc_006.re"
120 { res = stack_sub(); continue; }
121 #line 122 "calc_006.c"
122 yy13:
123 yych = *++YYCURSOR;
124 if (yych <= '/') goto yy14;
125 if (yych <= '9') goto yy17;
126 yy14:
127 #line 110 "calc_006.re"
128 { res = push_num(t, p, 10); continue; }
129 #line 130 "calc_006.c"
130 yy15:
131 yych = *++YYCURSOR;
132 if (yych <= '/') goto yy14;
133 if (yych <= '9') goto yy15;
134 goto yy14;
135 yy17:
136 yych = *++YYCURSOR;
137 if (yych <= '/') goto yy19;
138 if (yych <= '9') goto yy17;
139 yy19:
140 #line 109 "calc_006.re"
141 { res = push_num(t, p, 8); continue; }
142 #line 143 "calc_006.c"
143 }
144 #line 115 "calc_006.re"
145
146 }
147 return res;
148 }
149
main(int argc,char ** argv)150 int main(int argc, char **argv)
151 {
152 if (argc > 1)
153 {
154 char *inp;
155 int res = 0, argp = 0, len;
156
157 while(!res && ++argp < argc)
158 {
159 inp = strdup(argv[argp]);
160 len = strlen(inp);
161 if (inp[0] == '\"' && inp[len-1] == '\"')
162 {
163 inp[len - 1] = '\0';
164 ++inp;
165 }
166 res = scan(inp);
167 free(inp);
168 }
169 switch(res)
170 {
171 case 0:
172 printf("Result: %d\n", stack[0]);
173 return 0;
174 case 1:
175 fprintf(stderr, "Illegal character in input.\n");
176 return 1;
177 case 2:
178 fprintf(stderr, "Premature end of input.\n");
179 return 2;
180 case 3:
181 fprintf(stderr, "Stack overflow.\n");
182 return 3;
183 case 4:
184 fprintf(stderr, "Stack underflow.\n");
185 return 4;
186 }
187 }
188 else
189 {
190 fprintf(stderr, "%s <expr>\n", argv[0]);
191 return 0;
192 }
193 }
194