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