Mercurial > ~dholland > hg > ag > index.cgi
comparison examples/mpp/krc.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 * Sample C Grammar | |
6 * Compatible with Kernighan and Ritchie, 2nd. Edition. | |
7 * | |
8 * Copyright 1993-2000 Parsifal Software. All Rights Reserved. | |
9 * | |
10 * This software is provided 'as-is', without any express or implied | |
11 * warranty. In no event will the authors be held liable for any damages | |
12 * arising from the use of this software. | |
13 * | |
14 * Permission is granted to anyone to use this software for any purpose, | |
15 * including commercial applications, and to alter it and redistribute it | |
16 * freely, subject to the following restrictions: | |
17 * | |
18 * 1. The origin of this software must not be misrepresented; you must not | |
19 * claim that you wrote the original software. If you use this software | |
20 * in a product, an acknowledgment in the product documentation would be | |
21 * appreciated but is not required. | |
22 * 2. Altered source versions must be plainly marked as such, and must not be | |
23 * misrepresented as being the original software. | |
24 * 3. This notice may not be removed or altered from any source distribution. | |
25 */ | |
26 | |
27 #include "mpp.h" | |
28 | |
29 stack<unsigned> id_stack(100,20); | |
30 | |
31 } | |
32 [ | |
33 grammar token = program // Define grammar token | |
34 ~nest comments // Make it explicitly ANSI | |
35 sticky { statement} // resolves if-then-else conflict | |
36 event driven | |
37 // far tables // uncomment for 16 bit environment | |
38 ~allow macros | |
39 input values // token input | |
40 line numbers | |
41 //escape backslashes // uncomment if using MSVC++ | |
42 error trace // for diagnosing errors | |
43 parser name = cc // parser will be cc() | |
44 parser file name = "krc.cpp" | |
45 header file name = "krc.h" | |
46 default input type = token | |
47 ~test range // not necessary | |
48 enum { // See TOKEN.H | |
49 eof =0, | |
50 SPACE =' ', | |
51 ANDAND ='A', // "&&" | |
52 ANDassign, // "&=" | |
53 ARROW, // "->" | |
54 CONCAT, // "##" | |
55 DECR, // "--" | |
56 DIVassign, // "/=" | |
57 ELLIPSIS, // "..." | |
58 EQ, // "==" | |
59 ERassign, // "^=" | |
60 GE, // ">=" | |
61 ICR, // "++" | |
62 LE, // "<=" | |
63 LS, // "<<" | |
64 LSassign, // "<<=" | |
65 MODassign, // "%=" | |
66 MINUSassign, // "-=" | |
67 MULTassign, // "*=" | |
68 NE, // "!=" | |
69 ORassign, // "|=" | |
70 OROR, // "||" | |
71 PLUSassign, // "+=" | |
72 RS, // ">>" | |
73 RSassign, // ">>=" | |
74 CHARACTERconstant, // character constant | |
75 STRINGliteral, // character string | |
76 UNSIGNEDqualifier =97, | |
77 LONGqualifier, | |
78 FLOATqualifier, | |
79 HEXconstant =129, | |
80 OCTconstant, | |
81 DECconstant, | |
82 FLOATconstant, // real | |
83 NAME, | |
84 AUTO, // "auto" | |
85 BREAK, // "break" | |
86 CASE, // "case" | |
87 CHAR, // "char" | |
88 CONSTANT, // "const" | |
89 CONTINUE, // "continue" | |
90 DEFAULT, // "default" | |
91 DO, // "do" | |
92 DOUBLE, // "double" | |
93 ELSE, // "else" | |
94 ENUM, // "enum" | |
95 EXTERN, // "extern" | |
96 FLOAT, // "float" | |
97 FOR, // "for" | |
98 GOTO, // "goto" | |
99 IF, // "if" | |
100 INT, // "int" | |
101 LONG, // "long" | |
102 REGISTER, // "register" | |
103 RETURN, // "return" | |
104 SHORT, // "short" | |
105 SIGNED, // "signed" | |
106 SIZEOF, // "sizeof" | |
107 STATIC, // "static" | |
108 STRUCT, // "struct" | |
109 SWITCH, // "switch" | |
110 TYPEDEF, // "typedef" | |
111 UNION, // "union" | |
112 UNSIGNED, // "unsigned" | |
113 VOIDkey, // "void" | |
114 VOLATILE, // "volatile" | |
115 WHILE, // "while" | |
116 UNRECOGNIZED, | |
117 } | |
118 ] | |
119 | |
120 program | |
121 -> translation unit, eof | |
122 | |
123 translation unit | |
124 -> external declaration | |
125 -> translation unit, external declaration | |
126 | |
127 external declaration | |
128 -> function definition | |
129 -> declaration | |
130 | |
131 function definition | |
132 -> declarator, compound statement | |
133 -> declarator, declaration list, compound statement | |
134 -> declaration specifiers, declarator, compound statement | |
135 -> declaration specifiers, declarator, declaration list, compound statement | |
136 | |
137 declaration | |
138 -> declaration specifiers:m, init declarator list?, ';' =mark_typedef(m); | |
139 | |
140 declaration list | |
141 -> declaration | |
142 -> declaration list, declaration | |
143 | |
144 (int) declaration specifiers | |
145 -> storage class specifier | |
146 -> type specifier =0; | |
147 -> type qualifier =0; | |
148 -> declaration specifiers:m, storage class specifier:v =m | v; | |
149 -> declaration specifiers, type specifier | |
150 -> declaration specifiers, type qualifier | |
151 | |
152 (int) storage class specifier | |
153 -> AUTO =0; | |
154 -> REGISTER =0; | |
155 -> STATIC =0; | |
156 -> EXTERN =0; | |
157 -> TYPEDEF =1; | |
158 | |
159 type specifier | |
160 -> VOIDkey | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | |
161 -> struct or union specifier | |
162 -> enum specifier | |
163 -> typedef name | |
164 | |
165 type qualifier | |
166 -> CONSTANT | |
167 -> VOLATILE | |
168 | |
169 struct or union specifier | |
170 -> struct or union, identifier?, !++id_stack;, | |
171 '{', struct declaration list, '}' =--id_stack; | |
172 -> struct or union, identifier | |
173 | |
174 | |
175 struct or union | |
176 -> STRUCT | |
177 -> UNION | |
178 | |
179 struct declaration list | |
180 -> struct declaration | |
181 -> struct declaration list, struct declaration | |
182 | |
183 init declarator list | |
184 -> init declarator | |
185 -> init declarator list, ',', init declarator | |
186 | |
187 init declarator | |
188 -> declarator | |
189 -> declarator, '=', initializer | |
190 | |
191 struct declaration | |
192 -> specifier qualifier list, struct declarator list, ';' | |
193 | |
194 specifier qualifier list | |
195 -> type specifier | |
196 -> type qualifier | |
197 -> specifier qualifier list, type specifier | |
198 -> specifier qualifier list, type qualifier | |
199 | |
200 struct declarator list | |
201 -> struct declarator | |
202 -> struct declarator list, ',', struct declarator | |
203 | |
204 struct declarator | |
205 -> declarator | |
206 -> declarator?, ':', constant expression | |
207 | |
208 enum specifier | |
209 -> ENUM, identifier?, '{', enumerator list, '}' | |
210 -> ENUM, identifier | |
211 | |
212 enumerator list | |
213 -> enumerator | |
214 -> enumerator list, ',', enumerator | |
215 | |
216 enumerator | |
217 -> identifier | |
218 -> identifier, '=', constant expression | |
219 | |
220 declarator | |
221 -> direct declarator | |
222 -> pointer, direct declarator | |
223 | |
224 direct declarator | |
225 -> identifier:n =id_stack << n.handle; | |
226 -> '(', declarator, ')' | |
227 -> direct declarator, '[', constant expression?, ']' | |
228 -> direct declarator, '(', parameter type list, ')' | |
229 -> direct declarator, '(', identifier list?, ')' | |
230 | |
231 pointer | |
232 -> '*', type qualifier list? | |
233 -> '*', type qualifier list?, pointer | |
234 | |
235 type qualifier list | |
236 -> type qualifier | |
237 -> type qualifier list, type qualifier | |
238 | |
239 parameter type list | |
240 -> parameter list | |
241 -> parameter list, ',', ELLIPSIS | |
242 | |
243 parameter list | |
244 -> parameter declaration | |
245 -> parameter list, ',', parameter declaration | |
246 | |
247 parameter declaration | |
248 -> declaration specifiers, declarator | |
249 -> declaration specifiers, abstract declarator? | |
250 | |
251 identifier list | |
252 -> identifier | |
253 -> identifier list, ',', identifier | |
254 | |
255 initializer | |
256 -> assignment expression | |
257 -> '{', initializer list, '}' | |
258 -> '{', initializer list, ',', '}' | |
259 | |
260 initializer list | |
261 -> initializer | |
262 -> initializer list, ',', initializer | |
263 | |
264 type name | |
265 -> specifier qualifier list, abstract declarator? | |
266 | |
267 abstract declarator | |
268 -> pointer | |
269 -> direct abstract declarator | |
270 -> pointer, direct abstract declarator | |
271 | |
272 direct abstract declarator | |
273 -> '(', abstract declarator, ')' | |
274 -> '[', constant expression?, ']' | |
275 -> direct abstract declarator, '[', constant expression?, ']' | |
276 -> '(', parameter type list?, ')' | |
277 -> direct abstract declarator, '(', parameter type list?, ')' | |
278 | |
279 (token) identifier, typedef name | |
280 -> NAME:n =check_typedef(n); | |
281 | |
282 statement | |
283 -> labeled statement | |
284 -> expression statement | |
285 -> compound statement | |
286 -> selection statement | |
287 -> iteration statement | |
288 -> jump statement | |
289 | |
290 labeled statement | |
291 -> identifier, ':', statement | |
292 -> CASE, constant expression, ':', statement | |
293 -> DEFAULT, ':', statement | |
294 | |
295 expression statement | |
296 -> expression?, ';' | |
297 | |
298 compound statement | |
299 -> '{', statement list?, '}' | |
300 -> '{', declaration list, statement list?, '}' | |
301 | |
302 statement list | |
303 -> statement | |
304 -> statement list, statement | |
305 | |
306 selection statement | |
307 -> IF, '(', expression, ')', statement | |
308 -> IF, '(', expression, ')', statement, ELSE, statement | |
309 -> SWITCH, '(', expression, ')', statement | |
310 | |
311 iteration statement | |
312 -> WHILE, '(', expression, ')', statement | |
313 -> DO, statement, WHILE, '(', expression, ')', ';' | |
314 -> FOR, '(', expression?, ';', expression?, ';', expression?, ')', | |
315 statement | |
316 | |
317 jump statement | |
318 -> GOTO, identifier, ';' | |
319 -> CONTINUE, ';' | |
320 -> BREAK, ';' | |
321 -> RETURN, expression?, ';' | |
322 | |
323 expression | |
324 -> assignment expression | |
325 -> expression, ',', assignment expression | |
326 | |
327 assignment expression | |
328 -> conditional expression | |
329 -> unary expression, assignment operator, assignment expression | |
330 | |
331 assignment operator | |
332 -> '=' | MULTassign | DIVassign | MODassign | PLUSassign | MINUSassign | |
333 -> LSassign | RSassign | ANDassign | ORassign | ERassign | |
334 | |
335 conditional expression | |
336 -> logical or expression | |
337 -> logical or expression, '?', expression, ':', conditional expression | |
338 | |
339 constant expression | |
340 -> conditional expression | |
341 | |
342 logical or expression | |
343 -> logical and expression | |
344 -> logical or expression, OROR, logical and expression | |
345 | |
346 logical and expression | |
347 -> inclusive or expression | |
348 -> logical and expression, ANDAND, inclusive or expression | |
349 | |
350 inclusive or expression | |
351 -> exclusive or expression | |
352 -> inclusive or expression, '|', exclusive or expression | |
353 | |
354 exclusive or expression | |
355 -> and expression | |
356 -> exclusive or expression, '^', and expression | |
357 | |
358 and expression | |
359 -> equality expression | |
360 -> and expression, '&', equality expression | |
361 | |
362 equality expression | |
363 -> relational expression | |
364 -> equality expression, EQ, relational expression | |
365 -> equality expression, NE, relational expression | |
366 | |
367 relational expression | |
368 -> shift expression | |
369 -> relational expression, '<', shift expression | |
370 -> relational expression, '>', shift expression | |
371 -> relational expression, LE, shift expression | |
372 -> relational expression, GE, shift expression | |
373 | |
374 shift expression | |
375 -> additive expression | |
376 -> shift expression, LS, additive expression | |
377 -> shift expression, RS, additive expression | |
378 | |
379 additive expression | |
380 -> multiplicative expression | |
381 -> additive expression, '+', multiplicative expression | |
382 -> additive expression, '-', multiplicative expression | |
383 | |
384 multiplicative expression | |
385 -> cast expression | |
386 -> multiplicative expression, '*', cast expression | |
387 -> multiplicative expression, '/', cast expression | |
388 -> multiplicative expression, '%', cast expression | |
389 | |
390 cast expression | |
391 -> unary expression | |
392 -> '(', type name, ')', cast expression | |
393 | |
394 unary expression | |
395 -> postfix expression | |
396 -> ICR, unary expression | |
397 -> DECR, unary expression | |
398 -> unary operator, cast expression | |
399 -> SIZEOF, unary expression | |
400 -> SIZEOF, '(', type name, ')' | |
401 | |
402 unary operator | |
403 -> '&' | '*' | '+' | '-' | '~' | '!' | |
404 | |
405 postfix expression | |
406 -> primary expression | |
407 -> postfix expression, '[', expression, ']' | |
408 -> postfix expression, '(', argument expression list?, ')' | |
409 -> postfix expression, '.', identifier | |
410 -> postfix expression, ARROW, identifier | |
411 -> postfix expression, ICR | |
412 -> postfix expression, DECR | |
413 | |
414 primary expression | |
415 -> identifier | |
416 -> constant | |
417 -> STRINGliteral | |
418 -> '(', expression, ')' | |
419 | |
420 argument expression list | |
421 -> assignment expression | |
422 -> argument expression list, ',', assignment expression | |
423 | |
424 constant | |
425 -> HEXconstant | |
426 -> OCTconstant | |
427 -> DECconstant | |
428 -> FLOATconstant | |
429 -> CHARACTERconstant | |
430 | |
431 | |
432 { // Embedded C | |
433 #include <stack.h> | |
434 | |
435 | |
436 // Macro Definitions | |
437 | |
438 #define INPUT_CODE(T) (T).id | |
439 #define SYNTAX_ERROR syntax_error(PCB.error_message) | |
440 | |
441 | |
442 // Variable definitions | |
443 | |
444 static int use_count = 0; | |
445 symbol_type_enum symbol_table[N_SYMBOLS]; | |
446 | |
447 | |
448 /* | |
449 mark_typedef() gets a non_zero argument for typedef statements, a zero | |
450 argument otherwise. If the argument is non-zero it marks all stacked | |
451 identifiers as typedef_names. It then resets the id stack. | |
452 */ | |
453 | |
454 static void mark_typedef(int mask) { | |
455 unsigned x; | |
456 if (mask) { | |
457 while (size(id_stack)) { | |
458 id_stack >> x; | |
459 symbol_table[x] = typedef_name; | |
460 } | |
461 return; | |
462 } | |
463 reset(id_stack); | |
464 } | |
465 | |
466 /* | |
467 check_typedef() resolves a semantically determined productin by determining | |
468 whether a token is a typedef_name or not. If so it changes the reduction | |
469 token appropriately. | |
470 */ | |
471 | |
472 static token check_typedef(token t) { | |
473 if (symbol_table[t.handle] == typedef_name) | |
474 CHANGE_REDUCTION(typedef_name); | |
475 return t; | |
476 } | |
477 | |
478 | |
479 // Member Functions for Class c_parser | |
480 | |
481 // Constructor | |
482 | |
483 /* | |
484 This parser has no provisions for multiple simultaneous parses or for | |
485 recursion. The purpose of use_count is to make sure that there is only one | |
486 copy of the parser active at any time. | |
487 */ | |
488 | |
489 | |
490 c_parser::c_parser() { | |
491 assert(use_count == 0); | |
492 use_count++; | |
493 reset(id_stack); | |
494 memset(symbol_table, 0, sizeof(symbol_table)); | |
495 init_cc(); // init parse | |
496 } | |
497 | |
498 | |
499 // Destructor | |
500 | |
501 c_parser::~c_parser() { | |
502 use_count--; // Makes parser available | |
503 } | |
504 | |
505 | |
506 // Reset Parser | |
507 | |
508 c_parser &reset(c_parser &c) { | |
509 reset(id_stack); | |
510 memset(symbol_table, 0, sizeof(symbol_table)); | |
511 init_cc(); // init parse | |
512 return c; | |
513 } | |
514 | |
515 | |
516 // Transmit token to c_parser | |
517 | |
518 /* | |
519 The overloaded operator "<<" is used to transmit data to a parser. | |
520 Newline tokens are filtered out, since they are passed along by the | |
521 token scanner only in case text output of the preprocessor is | |
522 required. | |
523 | |
524 If the parser has encountered an error, there is no point in giving | |
525 it any further input. | |
526 | |
527 Otherwise, the input_code and input_value fields of the pcb are set | |
528 up and cc() is called to deal with the token. | |
529 */ | |
530 | |
531 token_sink &c_parser::operator << (token c) { | |
532 if (PCB.exit_flag != AG_RUNNING_CODE || (int) c.id == '\n') return *this; | |
533 PCB.input_code = c.id; | |
534 PCB.input_value = c; | |
535 cc(); | |
536 return *this; | |
537 } | |
538 | |
539 token_sink &c_parser::operator << (token *s) { | |
540 while (s->id != END_OF_FILE && PCB.exit_flag == AG_RUNNING_CODE) { | |
541 if ((int) s->id == 10) continue; | |
542 PCB.input_code = s->id; | |
543 PCB.input_value = *s++; | |
544 cc(); | |
545 } | |
546 return *this; | |
547 } | |
548 | |
549 } // End Embedded C | |
550 |