1 /* Generated by re2c */
2 #line 1 "calc_005.re"
3 // re2c $INPUT -o $OUTPUT
4 /* re2c lesson 001_upn_calculator, calc_005, (c) M. Boerger 2006 - 2007 */
5 #line 19 "calc_005.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 char * t,const char * l,int radix)17 int push_num(const char *t, const 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 - '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 return 0;
44 }
45
stack_sub()46 int stack_sub()
47 {
48 if (depth < 2) return 4;
49
50 --depth;
51 stack[depth-1] = stack[depth-1] - stack[depth];
52 return 0;
53 }
54
scan(char * s,int l)55 int scan(char *s, int l)
56 {
57 char *p = s;
58 char *q = 0;
59 char *t;
60 int res = 0;
61
62 #define YYCTYPE char
63 #define YYCURSOR p
64 #define YYLIMIT (s+l+1)
65 #define YYMARKER q
66 #define YYFILL(n) { return depth == 1 ? 0 : 2; }
67
68 while(!res)
69 {
70 t = p;
71
72 #line 73 "calc_005.c"
73 {
74 YYCTYPE yych;
75 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
76 yych = *YYCURSOR;
77 switch (yych) {
78 case '\t':
79 case ' ': goto yy4;
80 case '+': goto yy7;
81 case '-': goto yy9;
82 case '0': goto yy11;
83 case '1':
84 case '2':
85 case '3':
86 case '4':
87 case '5':
88 case '6':
89 case '7':
90 case '8':
91 case '9': goto yy13;
92 default: goto yy2;
93 }
94 yy2:
95 ++YYCURSOR;
96 #line 97 "calc_005.re"
97 { res = 1; continue; }
98 #line 99 "calc_005.c"
99 yy4:
100 ++YYCURSOR;
101 if (YYLIMIT <= YYCURSOR) YYFILL(1);
102 yych = *YYCURSOR;
103 switch (yych) {
104 case '\t':
105 case ' ': goto yy4;
106 default: goto yy6;
107 }
108 yy6:
109 #line 92 "calc_005.re"
110 { continue; }
111 #line 112 "calc_005.c"
112 yy7:
113 ++YYCURSOR;
114 #line 95 "calc_005.re"
115 { res = stack_add(); continue; }
116 #line 117 "calc_005.c"
117 yy9:
118 ++YYCURSOR;
119 #line 96 "calc_005.re"
120 { res = stack_sub(); continue; }
121 #line 122 "calc_005.c"
122 yy11:
123 yych = *++YYCURSOR;
124 switch (yych) {
125 case '0':
126 case '1':
127 case '2':
128 case '3':
129 case '4':
130 case '5':
131 case '6':
132 case '7':
133 case '8':
134 case '9': goto yy15;
135 default: goto yy12;
136 }
137 yy12:
138 #line 94 "calc_005.re"
139 { res = push_num(t, p, 10); continue; }
140 #line 141 "calc_005.c"
141 yy13:
142 ++YYCURSOR;
143 if (YYLIMIT <= YYCURSOR) YYFILL(1);
144 yych = *YYCURSOR;
145 switch (yych) {
146 case '0':
147 case '1':
148 case '2':
149 case '3':
150 case '4':
151 case '5':
152 case '6':
153 case '7':
154 case '8':
155 case '9': goto yy13;
156 default: goto yy12;
157 }
158 yy15:
159 ++YYCURSOR;
160 if (YYLIMIT <= YYCURSOR) YYFILL(1);
161 yych = *YYCURSOR;
162 switch (yych) {
163 case '0':
164 case '1':
165 case '2':
166 case '3':
167 case '4':
168 case '5':
169 case '6':
170 case '7':
171 case '8':
172 case '9': goto yy15;
173 default: goto yy17;
174 }
175 yy17:
176 #line 93 "calc_005.re"
177 { res = push_num(t, p, 8); continue; }
178 #line 179 "calc_005.c"
179 }
180 #line 98 "calc_005.re"
181
182 }
183 return res;
184 }
185
main(int argc,char ** argv)186 int main(int argc, char **argv)
187 {
188 if (argc > 1)
189 {
190 char *inp;
191 int res = 0, argp = 0, len;
192
193 while(!res && ++argp < argc)
194 {
195 inp = argv[argp];
196 len = strlen(inp);
197 if (inp[0] == '\"' && inp[len-1] == '\"')
198 {
199 ++inp;
200 len -=2;
201 }
202 res = scan(inp, len);
203 }
204 switch(res)
205 {
206 case 0:
207 printf("Result: %d\n", stack[0]);
208 return 0;
209 case 1:
210 fprintf(stderr, "Illegal character in input.\n");
211 return 1;
212 case 2:
213 fprintf(stderr, "Premature end of input.\n");
214 return 2;
215 case 3:
216 fprintf(stderr, "Stack overflow.\n");
217 return 3;
218 case 4:
219 fprintf(stderr, "Stack underflow.\n");
220 return 4;
221 }
222 }
223 else
224 {
225 fprintf(stderr, "%s <expr>\n", argv[0]);
226 return 0;
227 }
228 }
229