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