comparison examples/mpp/ex.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 {
2 /*
3 * AnaGram, a System for Syntax Directed Programming
4 * C Macro preprocessor
5 * Constant Expression Evaluator Module
6 *
7 * Copyright 1993-2000 Parsifal Software. All Rights Reserved.
8 *
9 * This software is provided 'as-is', without any express or implied
10 * warranty. In no event will the authors be held liable for any damages
11 * arising from the use of this software.
12 *
13 * Permission is granted to anyone to use this software for any purpose,
14 * including commercial applications, and to alter it and redistribute it
15 * freely, subject to the following restrictions:
16 *
17 * 1. The origin of this software must not be misrepresented; you must not
18 * claim that you wrote the original software. If you use this software
19 * in a product, an acknowledgment in the product documentation would be
20 * appreciated but is not required.
21 * 2. Altered source versions must be plainly marked as such, and must not be
22 * misrepresented as being the original software.
23 * 3. This notice may not be removed or altered from any source distribution.
24 */
25
26 #include "mpp.h"
27 }
28
29 [
30 //far tables // uncomment for 16 bit environment
31 ~allow macros
32 line numbers
33 //escape backslashes // uncomment if using MSVC++
34 default token type = long
35 default input type = token
36 ~declare pcb
37 ~diagnose errors
38 error trace
39 event driven
40 input values
41 ~test range
42 ~lines and columns
43 enum {
44 eof =0,
45 SPACE =' ',
46 ANDAND ='A', // "&&"
47 ANDassign, // "&="
48 ARROW, // "->"
49 CONCAT, // "##"
50 DECR, // "--"
51 DIVassign, // "/="
52 ELLIPSIS, // "..."
53 EQ, // "=="
54 ERassign, // "^="
55 GE, // ">="
56 ICR, // "++"
57 LE, // "<="
58 LS, // "<<"
59 LSassign, // "<<="
60 MODassign, // "%="
61 MINUSassign, // "-="
62 MULTassign, // "*="
63 NE, // "!="
64 ORassign, // "|="
65 OROR, // "||"
66 PLUSassign, // "+="
67 RS, // ">>"
68 RSassign, // ">>="
69 CHARACTERconstant, // character constant
70 STRINGliteral, // character string
71 HEXconstant =129,
72 OCTconstant,
73 DECconstant,
74 FLOATconstant, // real
75 NAME,
76 AUTO, // "auto"
77 BREAK, // "break"
78 CASE, // "case"
79 CHAR, // "char"
80 CONSTANT, // "const"
81 CONTINUE, // "continue"
82 DEFAULT, // "default"
83 DO, // "do"
84 DOUBLE, // "double"
85 ELSE, // "else"
86 ENUM, // "enum"
87 EXTERN, // "extern"
88 FLOAT, // "float"
89 FOR, // "for"
90 GOTO, // "goto"
91 IF, // "if"
92 INT, // "int"
93 LONG, // "long"
94 REGISTER, // "register"
95 RETURN, // "return"
96 SHORT, // "short"
97 SIGNED, // "signed"
98 SIZEOF, // "sizeof"
99 STATIC, // "static"
100 STRUCT, // "struct"
101 SWITCH, // "switch"
102 TYPEDEF, // "typedef"
103 UNION, // "union"
104 UNSIGNED, // "unsigned"
105 VOIDkey, // "void"
106 VOLATILE, // "volatile"
107 WHILE, // "while"
108 UNRECOGNIZED,
109 }
110 parser file name = "#.cpp"
111 ]
112
113 expression evaluator $
114 -> exp, eof
115
116 exp
117 -> conditional exp
118
119 conditional exp
120 -> logical or exp
121 -> logical or exp:c, '?', conditional exp:x, ':',
122 conditional exp:y = c != 0 ? x : y;
123
124 logical or exp
125 -> logical and exp
126 -> logical or exp:x, OROR, logical and exp:y =x != 0 || y!=0;
127
128 logical and exp
129 -> inclusive or exp
130 -> logical and exp:x, ANDAND, inclusive or exp:y =x != 0 && y !=0;
131
132 inclusive or exp
133 -> exclusive or exp
134 -> inclusive or exp:x, '|', exclusive or exp:y =x | y;
135
136 exclusive or exp
137 -> and exp
138 -> exclusive or exp:x, '^', and exp:y =x ^ y;
139
140 and exp
141 -> equality exp
142 -> and exp:x, '&', equality exp:y =x & y;
143
144 equality exp
145 -> relational exp
146 -> equality exp:x, EQ, relational exp:y =x == y;
147 -> equality exp:x, NE, relational exp:y =x != y;
148
149 relational exp
150 -> shift exp
151 -> relational exp:x, '<', shift exp:y =x < y;
152 -> relational exp:x, '>', shift exp:y =x > y;
153 -> relational exp:x, LE, shift exp:y =x <= y;
154 -> relational exp:x, GE, shift exp:y =x >= y;
155
156 shift exp
157 -> additive exp
158 -> shift exp:x, LS, additive exp:y =x << y;
159 -> shift exp:x, RS, additive exp:y =x >> y;
160
161 additive exp
162 -> multiplicative exp
163 -> additive exp:x, '+', multiplicative exp:y =x + y;
164 -> additive exp:x, '-', multiplicative exp:y =x - y;
165
166 multiplicative exp
167 -> unary exp
168 -> multiplicative exp:x, '*', unary exp:y =x * y;
169 -> multiplicative exp:x, '/', nonzero:y =x / y;
170 -> multiplicative exp:x, '%', nonzero:y =x % y;
171
172 nonzero
173 -> unary exp: x ={
174 if (x != 0) return x;
175 syntax_error("Divide by Zero");
176 PCB.exit_flag = 5;
177 return x;
178 }
179
180 unary exp
181 -> primary exp
182 -> '+', unary exp:x = x;
183 -> '-', unary exp:x = -x;
184 -> '~', unary exp:x = ~x;
185 -> '!', unary exp:x = !x;
186
187 primary exp
188 -> HEXconstant:x =decode("%lx",x.handle);
189 -> OCTconstant:x =decode("%lo",x.handle);
190 -> DECconstant:x =decode("%ld",x.handle);
191 -> CHARACTERconstant:x =decode("'%lc'",x.handle);
192 -> NAME =0;
193 -> '(', conditional exp:x, ')' =x;
194
195
196 { // Embedded C
197 #include <stdio.h>
198
199
200 // Macro Definitions
201
202 #define PCB (*ex_pcb)
203 #define SYNTAX_ERROR syntax_error("Syntax error in constant expression");
204
205
206 // Static data
207
208 static ex_pcb_type *ex_pcb; // Pointer to active pcb
209
210
211 /*
212
213 decode() is a simple function to recover the numeric value of a
214 token. Its task is somewhat simplified by the fact that the only
215 values allowed in this example are longs.
216
217 */
218
219 static long decode(const char *fmt, unsigned ndx) {
220 long v;
221 sscanf(td[ndx], fmt, &v);
222 return v;
223 }
224
225
226 // Members of expression_evaluator Class
227
228
229 // Constructor
230
231 /*
232 Each expression_evaluator has its own parser control block.
233 Therefore, before calling ex() or its initializer init_ex() it is
234 necessary to make sure the pcb pointer for ex() is correctly set.
235 */
236
237 expression_evaluator::expression_evaluator() {
238 ex_pcb = &pcb; // set up pointer to pcb
239 init_ex(); // init parser
240 }
241
242
243 // Reset expression_evaluator
244
245 token_sink& reset(expression_evaluator &x) {
246 ex_pcb = &x.pcb; // set up pointer to pcb
247 init_ex(); // init parser
248 return x;
249 }
250
251
252 // Xmit Token to expression_evaluator
253
254 /*
255 There could be space tokens in the input to the expression
256 evaluator, but they are never significant so it is acceptable to
257 filter them out on input.
258
259 If the expression_evaluator has encountered an error, there is no
260 point in giving it any further input.
261
262 Otherwise, the input_code and input_value fields of the pcb are set
263 up, the pcb pointer for ex is set, and ex() is called to deal with
264 the token.
265
266 When looping, it is only necessary to set up ex_pcb at the
267 beginning of the loop.
268 */
269
270 token_sink& expression_evaluator::operator << (token t) {
271 if (t.id == SPACE || pcb.exit_flag != AG_RUNNING_CODE) return *this;
272 pcb.input_code = t.id;
273 pcb.input_value = t;
274 ex_pcb = &pcb;
275 ex();
276 return *this;
277 }
278
279 token_sink &expression_evaluator::operator << (token *tp) {
280 ex_pcb = &pcb;
281 while (pcb.exit_flag == AG_RUNNING_CODE) {
282 if (pcb.input_code == SPACE) continue;
283 pcb.input_code = tp->id;
284 pcb.input_value = *tp++;
285 ex();
286 }
287 return *this;
288 }
289
290
291 // Return Value of expression_evaluator
292
293 /*
294 The (long) cast operator is overloaded to provide a mechanism to
295 retrieve the value of the expression evaluated by the
296 expression_evaluator.
297
298 If there was a syntax error, the return value is zero.
299 */
300
301 expression_evaluator::operator long() {
302 ex_pcb = &pcb;
303 if (pcb.exit_flag == AG_SUCCESS_CODE) return ex_value();
304 else return 0;
305 }
306
307 /*
308 // Check expression_evaluator for error
309
310 int error(expression_evaluator &x) {
311 return x.pcb.exit_flag != AG_SUCCESS_CODE;
312 }
313 */
314 } // End of Embedded C