comparison tests/agcl/examples/good/mas.cpp @ 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 * AnaGram, a System for Syntax Directed Programming
3 * C Macro preprocessor
4 * Macro argument substitution module
5 *
6 * Copyright 1993-2000 Parsifal Software. All Rights Reserved.
7 *
8 * This software is provided 'as-is', without any express or implied
9 * warranty. In no event will the authors be held liable for any damages
10 * arising from the use of this software.
11 *
12 * Permission is granted to anyone to use this software for any purpose,
13 * including commercial applications, and to alter it and redistribute it
14 * freely, subject to the following restrictions:
15 *
16 * 1. The origin of this software must not be misrepresented; you must not
17 * claim that you wrote the original software. If you use this software
18 * in a product, an acknowledgment in the product documentation would be
19 * appreciated but is not required.
20 * 2. Altered source versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source distribution.
23 */
24
25 #include "mpp.h"
26
27
28 /*
29 * AnaGram, A System for Syntax Directed Programming
30 * File generated by: ...
31 *
32 * AnaGram Parsing Engine
33 * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
34 *
35 * This software is provided 'as-is', without any express or implied
36 * warranty. In no event will the authors be held liable for any damages
37 * arising from the use of this software.
38 *
39 * Permission is granted to anyone to use this software for any purpose,
40 * including commercial applications, and to alter it and redistribute it
41 * freely, subject to the following restrictions:
42 *
43 * 1. The origin of this software must not be misrepresented; you must not
44 * claim that you wrote the original software. If you use this software
45 * in a product, an acknowledgment in the product documentation would be
46 * appreciated but is not required.
47 * 2. Altered source versions must be plainly marked as such, and must not be
48 * misrepresented as being the original software.
49 * 3. This notice may not be removed or altered from any source distribution.
50 */
51
52 #ifndef MAS_H
53 #include "mas.h"
54 #endif
55
56 #ifndef MAS_H
57 #error Mismatched header file
58 #endif
59
60 #include <ctype.h>
61 #include <stdio.h>
62
63 #define RULE_CONTEXT (&((PCB).cs[(PCB).ssx]))
64 #define ERROR_CONTEXT ((PCB).cs[(PCB).error_frame_ssx])
65 #define CONTEXT ((PCB).cs[(PCB).ssx])
66
67
68 #define CHANGE_REDUCTION(x) mas_change_reduction(mas_##x##_token)
69 int mas_change_reduction(mas_token_type);
70
71 #define INPUT_VALUE(type) *(type *) &(PCB).input_value
72
73 #line - "mas.syn"
74 // Embedded C
75 #include "array.h" // AnaGram\CLASSLIB\INCLUDE\array.h
76 #include "stack.h" // AnaGram\CLASSLIB\INCLUDE\stack.h
77
78
79 // Macro Definitions
80
81 #define INPUT_CODE(T) (T).id
82 #define PCB (*mas_pcb)
83 #define SYNTAX_ERROR syntax_error(PCB.error_message);
84
85
86 // Static variables
87
88 typedef stack<unsigned> unsigned_stack; // accomodate broken compilers
89
90 static unsigned_stack active_macros(200,20);
91 static token **args;
92 static int args_only = 0;
93 static mas_pcb_type *mas_pcb;
94 static int n_concats = 0;
95 static int n_args;
96 static unsigned *params;
97 static token_accumulator space_stack(100);
98
99
100 /*
101
102 expand_text() is a shell procedure which calls the mas parser a
103 number of times. It is used to expand arguments before substituting
104 them into a macro, and to expand the body of a macro. Notice that
105 expand_text() is recursive, since macros encountered during the an
106 expansion process may themselves need to be expanded.
107
108 expand_text() takes three explicit arguments:
109 token *text:
110 points to a string of tokens, terminated by an eof token.
111
112 int n:
113 specifies the number of arguments. Defaults to 0. The arguments
114 themselves are token strings on the token accumulator stack.
115 expand_text() makes copies of them and stores pointers to them in
116 the args array.
117
118 unsigned *p:
119 An array of n dictionary indices which gives the names of the
120 parameters for which the arguments are to be substituted. p
121 defaults to NULL.
122
123 global switches
124 Two global switches affect the expansion of text: if_clause and
125 args_only. Setting if_clause affects the treatment of the token
126 "defined". Setting args_only causes only macro parameters to be
127 expanded.
128
129 */
130
131 void expand_text(token *text, int n, unsigned *p) {
132 mas_pcb_type pcb;
133
134 // Save old status
135 mas_pcb_type *save_pcb = mas_pcb;
136 int save_n_args = n_args;
137 token **save_args = args;
138 unsigned *save_params = params;
139 int save_switch = args_only;
140
141 // pop args from accumlator stack and expand them
142 args_only = 0;
143 token **new_args;
144 int k = n;
145 if (n) {
146 new_args = new token*[n];
147 args_only = 1;
148 while (k--) {
149 token t;
150 token top = *(token *) ta;
151 while (top.id == SPACE) ta >> t; //trim space on right
152 array<token> arg_tokens(ta, size(ta) + 1);
153 token *tp = arg_tokens;
154 while (tp->id == SPACE) tp++; //trim space on left
155 --ta;
156 mas_pcb = &pcb;
157 pcb.pointer = tp;
158 ++ta;
159 mas();
160 new_args[k] = copy(ta);
161 --ta;
162 }
163 args_only = 0;
164 }
165 else new_args = NULL;
166
167 // Expand text
168 args = new_args;
169 n_args = n;
170 params = p;
171 pcb.pointer = text;
172 mas_pcb = &pcb;
173 ++ta;
174 ++active_macros;
175 n_concats = 0;
176 mas();
177
178 // If any new tokens were created by concatenation, rescan
179 while (n_concats) {
180 array<token> expansion(ta,size(ta) + 1);
181 --ta;
182 pcb.pointer = expansion;
183 ++ta;
184 n_concats = 0;
185 n = size(active_macros);
186
187 #ifdef _MSC_VER //Cope with peculiarity of MSVC++
188 while (n--) macro[*((unsigned *)active_macros + n)].busy_flag = 1;
189 #else
190 while (n--) macro[active_macros[n]].busy_flag = 1;
191 #endif
192 mas();
193 }
194 n = size(active_macros);
195 #ifdef _MSC_VER //Cope with peculiarity of MSVC++
196 while (n--) macro[*((unsigned *)active_macros + n)].busy_flag = 0;
197 #else
198 while (n--) macro[active_macros[n]].busy_flag = 0;
199 #endif
200 --active_macros;
201
202 // Discard argument strings
203
204 n = n_args;
205 while (n--) delete [] args[n];
206 if (n_args) delete [] args;
207
208 // Restore old status
209
210 args_only = save_switch;
211 args = save_args;
212 n_args = save_n_args;
213 params = save_params;
214 mas_pcb = save_pcb;
215 }
216
217 /*
218
219 expand_macro() is a shell procedure which sets up a call to
220 expand_text for a specific macro.
221
222 */
223
224 void expand_macro(token t, unsigned n_args) {
225 unsigned id = macro_id[t.handle];
226 token *body = macro[id].body;
227 assert(n_args == macro[id].n_args);
228 if (body == NULL) {
229 while (n_args--) --ta;
230 ++ta;
231 return;
232 }
233 expand_text(body,n_args,macro[id].arg_names);
234 }
235
236 /*
237
238 expand_arg() is another shell procedure for expand_text() which does
239 a complete expansion of a single macro argument.
240
241 */
242
243 static void expand_arg(unsigned n) {
244 expand_text(args[n]);
245 concat(ta);
246 }
247
248 /*
249
250 id_macro() is very nearly the same as id_macro() in TS.SYN. The
251 primary difference is that this one deals in tokens, the other in
252 character strings.
253
254 */
255
256 static token id_macro(token t) {
257 unsigned n = n_args;
258 unsigned id;
259
260 while (n--) if (t.handle == params[n]) {
261 CHANGE_REDUCTION(parameter_name);
262 t.handle = n;
263 return t;
264 }
265 if (args_only) return t;
266 if (if_clause && t.handle == defined_value) {
267 CHANGE_REDUCTION(defined);
268 return t;
269 }
270 id = macro_id[t.handle];
271 if (id == 0) return t;
272 if (macro[id].busy_flag) return t;
273 active_macros << id;
274 if (macro[id].parens) CHANGE_REDUCTION(macro);
275 else CHANGE_REDUCTION(simple_macro);
276 return t;
277 }
278
279 /*
280
281 defined() is very nearly the same as defined() in TS.SYN. The primary
282 difference is that this one deals in tokens, the other in character
283 strings.
284
285 */
286
287 static token defined(unsigned handle) {
288 token t;
289 t.id = DECconstant;
290 t.handle = macro_id[handle] ? one_value : zero_value;
291 return t;
292 }
293
294 /*
295
296 concatenate() implements the splicing together of two tokens by the
297 "##" operator in a macro definition. Because of the way the grammar
298 has been written, spaces have already been trimmed on both sides of the
299 ## by the parser.
300
301 If there are actually two tokens to concatenate, the last token on
302 the left is popped off, its string value is obtained from the token
303 dictionary and pushed onto the string accumulator, ditto for the
304 first token on the right. The string is then identified and the token
305 is classified. If the new token is the name of a macro, a new scan
306 will be required to expand it.
307
308 */
309
310 static void concatenate(void) {
311 array<token> right_arg(ta, size(ta) + 1);
312 token t;
313 token *tp = right_arg;
314
315 --ta; // discard right argument from stack
316
317 if (size(ta) && tp->id != END_OF_FILE) {
318 ta >> t; // pop left token
319 ++sa << td[t.handle] << td[tp->handle]; // left string + right string
320 t.handle = td << sa.top(); // identify string
321 t.id = classify_token(sa.top()); // classify token
322 --sa; // discard string
323 ++tp; // discard old token on right
324 if (macro_id[t.handle]) n_concats++; // if macro, signal rescan
325 ta << t; // output new token
326 }
327 ta << tp; // remainder of right side
328 }
329
330 /*
331
332 make_string() implements the '#' operator in macro expansions, that
333 is, it turns its operand into a string constant. To do this it must
334 provide "" marks and must quote any embedded " or \ characters with
335 the \ character.
336
337 */
338
339 static token make_string(unsigned n) {
340 token *tp;
341 token t;
342
343 tp = args[n];
344 ++sa << '"';
345 while (tp->id != END_OF_FILE) {
346 char *p = td[tp->handle];
347 char c;
348 while ((c = *p++) != 0) {
349 if (c == '"' || c == '\\') sa << '\\';
350 sa << c;
351 }
352 tp++;
353 }
354 sa << '"';
355 t.id = STRINGliteral;
356 t.handle = td << sa.top();
357 --sa;
358 return t;
359 }
360
361 #line - "mas.cpp"
362
363 #ifndef CONVERT_CASE
364 #define CONVERT_CASE(c) (c)
365 #endif
366 #ifndef TAB_SPACING
367 #define TAB_SPACING 8
368 #endif
369
370 static void ag_rp_1(void) {
371 #line - "mas.syn"
372 reset(space_stack);
373 #line - "mas.cpp"
374 }
375
376 static void ag_rp_2(token s) {
377 #line - "mas.syn"
378 if (args_only) space_stack << s;
379 #line - "mas.cpp"
380 }
381
382 static void ag_rp_3(void) {
383 #line - "mas.syn"
384 ta << space_stack;
385 #line - "mas.cpp"
386 }
387
388 static void ag_rp_4(void) {
389 #line - "mas.syn"
390 ta << space_stack;
391 #line - "mas.cpp"
392 }
393
394 static void ag_rp_5(token t) {
395 #line - "mas.syn"
396 ta << t << space_stack;
397 #line - "mas.cpp"
398 }
399
400 static void ag_rp_6(token t) {
401 #line - "mas.syn"
402 ta << t;
403 #line - "mas.cpp"
404 }
405
406 static void ag_rp_7(token n) {
407 #line - "mas.syn"
408 ta << make_string(n.handle);
409 #line - "mas.cpp"
410 }
411
412 static void ag_rp_8(token t) {
413 #line - "mas.syn"
414 ta << t;
415 #line - "mas.cpp"
416 }
417
418 static void ag_rp_9(token t) {
419 #line - "mas.syn"
420 expand_macro(t,0), concat(ta);
421 #line - "mas.cpp"
422 }
423
424 static void ag_rp_10(token t, unsigned n) {
425 #line - "mas.syn"
426 expand_macro(t,n), concat(ta);
427 #line - "mas.cpp"
428 }
429
430 static void ag_rp_11(token n) {
431 #line - "mas.syn"
432 ta << defined(n.handle);
433 #line - "mas.cpp"
434 }
435
436 static token ag_rp_12(token n) {
437 #line - "mas.syn"
438 return n;
439 #line - "mas.cpp"
440 }
441
442 static token ag_rp_13(token n) {
443 #line - "mas.syn"
444 return n;
445 #line - "mas.cpp"
446 }
447
448 static token ag_rp_14(token n) {
449 #line - "mas.syn"
450 return id_macro(n);
451 #line - "mas.cpp"
452 }
453
454 static void ag_rp_15(token name) {
455 #line - "mas.syn"
456 expand_arg(name.handle), ta << space_stack;
457 #line - "mas.cpp"
458 }
459
460 static void ag_rp_16(token name) {
461 #line - "mas.syn"
462 ta << args[name.handle], concatenate();
463 #line - "mas.cpp"
464 }
465
466 static void ag_rp_17(void) {
467 #line - "mas.syn"
468 concatenate();
469 #line - "mas.cpp"
470 }
471
472 static void ag_rp_18(token n) {
473 #line - "mas.syn"
474 ta << args[n.handle], ++ta;
475 #line - "mas.cpp"
476 }
477
478 static void ag_rp_19(void) {
479 #line - "mas.syn"
480 ++ta;
481 #line - "mas.cpp"
482 }
483
484 static void ag_rp_20(token t) {
485 #line - "mas.syn"
486 ta << t, ++ta;
487 #line - "mas.cpp"
488 }
489
490 static void ag_rp_21(void) {
491 #line - "mas.syn"
492 ++ta;
493 #line - "mas.cpp"
494 }
495
496 static void ag_rp_22(token t) {
497 #line - "mas.syn"
498 ta << t;
499 #line - "mas.cpp"
500 }
501
502 static void ag_rp_23(token n) {
503 #line - "mas.syn"
504 ta << make_string(n.handle);
505 #line - "mas.cpp"
506 }
507
508 static void ag_rp_24(token t) {
509 #line - "mas.syn"
510 ta << t;
511 #line - "mas.cpp"
512 }
513
514 static unsigned ag_rp_25(void) {
515 #line - "mas.syn"
516 return 0;
517 #line - "mas.cpp"
518 }
519
520 static unsigned ag_rp_26(void) {
521 #line - "mas.syn"
522 return 1;
523 #line - "mas.cpp"
524 }
525
526 static unsigned ag_rp_27(unsigned n) {
527 #line - "mas.syn"
528 return n+1;
529 #line - "mas.cpp"
530 }
531
532 static void ag_rp_28(token t) {
533 #line - "mas.syn"
534 ++ta << t;
535 #line - "mas.cpp"
536 }
537
538 static void ag_rp_29(token t) {
539 #line - "mas.syn"
540 ta << t;
541 #line - "mas.cpp"
542 }
543
544 static void ag_rp_30(token t) {
545 #line - "mas.syn"
546 ta << t;
547 #line - "mas.cpp"
548 }
549
550 static void ag_rp_31(token t) {
551 #line - "mas.syn"
552 concat(ta) << t;
553 #line - "mas.cpp"
554 }
555
556 static void ag_rp_32(token t) {
557 #line - "mas.syn"
558 ++ta << t;
559 #line - "mas.cpp"
560 }
561
562 static void ag_rp_33(token t) {
563 #line - "mas.syn"
564 ta << t;
565 #line - "mas.cpp"
566 }
567
568
569 #ifndef AG_TRACE_FILE_NAME
570 #define AG_TRACE_FILE_NAME "mas.etr"
571 #endif
572
573 static void ag_trace_error(void) {
574 FILE *ag_file = fopen(AG_TRACE_FILE_NAME, "w");
575 int i;
576 if (ag_file == NULL) return;
577 fprintf(ag_file, "%d\n", (PCB).ssx);
578 for (i = 0; i < (PCB).ssx; i++) fprintf(ag_file, "%d\n", (PCB).ss[i]);
579 fprintf(ag_file, "%d\n", (PCB).sn);
580 fprintf(ag_file, "%d\n", (PCB).token_number);
581 fclose(ag_file);
582 }
583
584
585 #define READ_COUNTS
586 #define WRITE_COUNTS
587 #undef V
588 #define V(i,t) (*t (&(PCB).vs[(PCB).ssx + i]))
589 #undef VS
590 #define VS(i) (PCB).vs[(PCB).ssx + i]
591
592 #ifndef GET_CONTEXT
593 #define GET_CONTEXT CONTEXT = (PCB).input_context
594 #endif
595
596 typedef enum {
597 ag_action_1,
598 ag_action_2,
599 ag_action_3,
600 ag_action_4,
601 ag_action_5,
602 ag_action_6,
603 ag_action_7,
604 ag_action_8,
605 ag_action_9,
606 ag_action_10,
607 ag_action_11,
608 ag_action_12
609 } ag_parser_action;
610
611
612 #ifndef NULL_VALUE_INITIALIZER
613 #define NULL_VALUE_INITIALIZER = { 0 }
614 #endif
615
616 static mas_vs_type const ag_null_value NULL_VALUE_INITIALIZER;
617
618 static const unsigned char ag_rpx[] = {
619 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
620 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 25,
621 26, 27, 28, 29, 30, 31, 0, 0, 32, 0, 33
622 };
623
624 #define AG_TCV(x) ag_tcv[(x)]
625
626 static const unsigned char ag_tcv[] = {
627 6, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
628 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 7, 34, 34, 13,
629 34, 34, 34, 34, 17, 19, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34,
630 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 25, 34, 34, 34,
631 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
632 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
633 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
634 34, 34, 34, 34, 34, 34, 34, 22, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
635 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
636 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
637 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
638 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
639 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
640 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
641 34, 34, 34, 34
642 };
643
644 #ifndef SYNTAX_ERROR
645 #define SYNTAX_ERROR fprintf(stderr,"%s\n", (PCB).error_message)
646 #endif
647
648 #ifndef PARSER_STACK_OVERFLOW
649 #define PARSER_STACK_OVERFLOW {fprintf(stderr, \
650 "\nParser stack overflow\n");}
651 #endif
652
653 #ifndef REDUCTION_TOKEN_ERROR
654 #define REDUCTION_TOKEN_ERROR {fprintf(stderr, \
655 "\nReduction token error\n");}
656 #endif
657
658
659 #ifndef INPUT_CODE
660 #define INPUT_CODE(T) (T)
661 #endif
662
663
664
665 static const int ag_rtt[] = {
666 15, 14, 16, 11, 20, 0
667 };
668
669 static const unsigned char ag_tstt[] = {
670 34,28,22,19,17,13,7,6,0,1,2,
671 34,28,22,19,17,13,7,6,0,3,4,5,8,9,10,11,14,15,16,20,23,
672 34,28,22,19,17,13,7,0,1,
673 22,17,7,0,1,21,
674 22,0,14,
675 34,28,25,22,19,17,13,7,6,0,1,
676 34,28,25,22,19,17,13,7,6,0,1,
677 34,28,25,22,19,17,13,7,6,0,1,
678 34,28,25,22,19,17,13,7,6,0,1,
679 34,28,22,19,17,13,0,3,8,9,10,11,14,15,16,20,23,
680 6,0,
681 34,28,22,19,17,13,7,0,11,14,15,16,20,24,26,
682 22,17,7,0,
683 25,7,0,
684 25,17,7,0,
685 25,7,0,
686 25,7,0,
687 22,0,14,
688 22,7,0,1,
689 34,28,25,22,19,17,13,7,0,1,18,
690 22,7,0,
691 34,25,22,17,13,7,0,27,29,31,
692 28,19,0,
693 19,7,0,1,
694 34,28,25,22,19,17,13,7,0,31,32,
695 34,25,22,17,13,7,0,31,32,
696 34,25,22,17,13,7,0,1,
697 19,7,0,
698 34,28,25,22,19,17,13,7,0,31,32,
699 34,25,22,17,13,7,0,27,29,31,
700 34,25,22,17,13,7,0,31,32,
701
702 };
703
704
705 static unsigned const char ag_astt[244] = {
706 4,4,4,4,4,4,4,4,7,1,0,2,2,2,2,2,1,10,8,7,1,1,1,1,1,1,1,1,2,2,1,1,4,4,4,4,4,
707 4,4,7,1,4,4,4,7,1,2,2,7,2,4,4,4,4,4,4,4,4,4,7,1,4,4,4,4,4,4,4,4,4,7,1,4,4,
708 4,4,4,4,4,4,4,7,1,4,4,4,4,4,4,4,4,4,7,1,2,2,2,2,2,1,5,3,3,1,1,1,1,2,2,1,1,
709 3,7,2,2,2,2,2,1,10,7,2,2,2,2,2,2,2,2,1,10,7,2,10,4,2,1,10,4,2,10,4,2,10,4,
710 2,7,2,4,4,7,1,4,4,4,4,4,4,4,4,7,1,1,1,10,7,2,2,2,2,2,10,4,1,1,1,1,2,7,4,4,
711 7,1,2,10,2,2,2,2,2,2,7,1,3,2,2,2,2,2,2,4,1,3,4,4,4,4,4,4,7,1,2,10,7,2,10,2,
712 2,2,2,2,2,7,1,3,2,2,2,2,2,10,7,1,1,1,2,2,2,2,2,2,4,1,3
713 };
714
715
716 static const unsigned char ag_pstt[] = {
717 6,6,6,6,6,6,6,6,0,1,0,
718 12,12,20,12,12,4,7,10,1,9,9,10,9,8,7,6,5,14,15,3,2,
719 6,6,6,6,6,6,6,2,11,
720 6,6,6,3,12,17,
721 20,4,13,
722 6,6,6,6,6,6,6,6,6,5,13,
723 6,6,6,6,6,6,6,6,6,6,14,
724 6,6,6,6,6,6,6,6,6,7,15,
725 6,6,6,6,6,6,6,6,6,8,16,
726 12,12,20,12,12,4,4,2,2,8,7,6,5,14,15,3,2,
727 5,10,
728 28,28,20,28,28,17,7,11,30,22,30,30,30,23,30,
729 18,18,7,12,
730 24,7,21,
731 26,19,7,11,
732 27,7,10,
733 25,7,9,
734 20,17,29,
735 6,6,18,20,
736 6,6,6,6,6,6,6,6,19,21,22,
737 23,7,20,
738 38,38,38,44,38,7,35,25,25,24,
739 26,16,22,
740 6,6,23,27,
741 40,46,40,40,39,44,40,40,24,28,45,
742 40,40,40,44,40,40,36,28,43,
743 6,6,6,6,6,6,26,29,
744 19,7,27,
745 40,46,40,40,41,44,40,40,28,28,45,
746 38,38,38,44,38,7,29,30,30,24,
747 40,40,40,44,40,40,37,28,43,
748
749 };
750
751
752 static const unsigned char ag_sbt[] = {
753 0, 11, 32, 41, 47, 50, 61, 72, 83, 94, 111, 113, 128, 132,
754 135, 139, 142, 145, 148, 152, 163, 166, 176, 179, 183, 194, 203, 211,
755 214, 225, 235, 244
756 };
757
758
759 static const unsigned char ag_sbe[] = {
760 8, 19, 39, 44, 48, 59, 70, 81, 92, 100, 112, 120, 131, 134,
761 138, 141, 144, 146, 150, 160, 165, 172, 178, 181, 191, 200, 209, 213,
762 222, 231, 241, 244
763 };
764
765
766 static const unsigned char ag_fl[] = {
767 1,1,2,0,1,3,0,2,1,2,2,2,1,2,1,1,5,2,2,6,1,2,3,3,3,3,3,3,1,2,1,1,1,1,1,
768 1,2,4,1,2,1,2,1,2,1,2,2
769 };
770
771 static const unsigned char ag_ptt[] = {
772 0, 4, 4, 5, 5, 2, 1, 1, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9,
773 21, 21, 15, 8, 10, 10, 23, 23, 23, 23, 24, 24, 24, 26, 26, 26, 26, 18,
774 18, 18, 29, 29, 32, 32, 27, 27, 31, 31, 31
775 };
776
777 static const unsigned char *ag_valid(int ag_k) {
778 const unsigned char *ag_tp = &ag_tstt[ag_sbt[(PCB).sn+1]];
779 while (*--ag_tp != (unsigned char) ag_k) if (*ag_tp == 0) return NULL;
780 return ag_tp;
781 }
782
783 int mas_change_reduction(mas_token_type ag_k) {
784 if (!ag_valid(ag_k)) return 0;
785 (PCB).reduction_token = ag_k;
786 return 1;
787 }
788
789 static void ag_default(const int *ag_tp) {
790 (PCB).ag_dsn = (PCB).sn;
791 (PCB).ag_dtl = ag_tp;
792 while (!ag_valid((mas_token_type) *ag_tp)) ag_tp++;
793 (PCB).reduction_token = (mas_token_type) *ag_tp;
794 }
795
796
797
798 static void ag_ra(void)
799 {
800 switch(ag_rpx[(PCB).ag_ap]) {
801 case 1: ag_rp_1(); break;
802 case 2: ag_rp_2(V(1,(token *))); break;
803 case 3: ag_rp_3(); break;
804 case 4: ag_rp_4(); break;
805 case 5: ag_rp_5(V(0,(token *))); break;
806 case 6: ag_rp_6(V(0,(token *))); break;
807 case 7: ag_rp_7(V(1,(token *))); break;
808 case 8: ag_rp_8(V(0,(token *))); break;
809 case 9: ag_rp_9(V(0,(token *))); break;
810 case 10: ag_rp_10(V(0,(token *)), V(3,(unsigned *))); break;
811 case 11: ag_rp_11(V(1,(token *))); break;
812 case 12: V(0,(token *)) = ag_rp_12(V(1,(token *))); break;
813 case 13: V(0,(token *)) = ag_rp_13(V(3,(token *))); break;
814 case 14: ag_default(&ag_rtt[0]); V(0,(token *)) = ag_rp_14(V(0,(token *))); break;
815 case 15: ag_rp_15(V(0,(token *))); break;
816 case 16: ag_rp_16(V(2,(token *))); break;
817 case 17: ag_rp_17(); break;
818 case 18: ag_rp_18(V(0,(token *))); break;
819 case 19: ag_rp_19(); break;
820 case 20: ag_rp_20(V(0,(token *))); break;
821 case 21: ag_rp_21(); break;
822 case 22: ag_rp_22(V(0,(token *))); break;
823 case 23: ag_rp_23(V(1,(token *))); break;
824 case 24: ag_rp_24(V(0,(token *))); break;
825 case 25: V(0,(unsigned *)) = ag_rp_25(); break;
826 case 26: V(0,(unsigned *)) = ag_rp_26(); break;
827 case 27: V(0,(unsigned *)) = ag_rp_27(V(0,(unsigned *))); break;
828 case 28: ag_rp_28(V(0,(token *))); break;
829 case 29: ag_rp_29(V(1,(token *))); break;
830 case 30: ag_rp_30(V(0,(token *))); break;
831 case 31: ag_rp_31(V(1,(token *))); break;
832 case 32: ag_rp_32(V(0,(token *))); break;
833 case 33: ag_rp_33(V(1,(token *))); break;
834 }
835 (PCB).la_ptr = (PCB).pointer;
836 }
837
838 #define TOKEN_NAMES mas_token_names
839 const char *const mas_token_names[35] = {
840 "grammar",
841 "space",
842 "grammar",
843 "parse unit",
844 "",
845 "",
846 "eof",
847 "' '",
848 "parameter expansion",
849 "simple parse unit",
850 "concatenation",
851 "macro",
852 "",
853 "'#'",
854 "parameter name",
855 "variable",
856 "simple macro",
857 "'('",
858 "macro arg list",
859 "')'",
860 "defined",
861 "macro name",
862 "NAME",
863 "left side",
864 "right side",
865 "CONCAT",
866 "not parameter",
867 "arg elements",
868 "','",
869 "initial arg element",
870 "",
871 "nested elements",
872 "arg element",
873 "",
874 "",
875
876 };
877
878 #ifndef MISSING_FORMAT
879 #define MISSING_FORMAT "Missing %s"
880 #endif
881 #ifndef UNEXPECTED_FORMAT
882 #define UNEXPECTED_FORMAT "Unexpected %s"
883 #endif
884 #ifndef UNNAMED_TOKEN
885 #define UNNAMED_TOKEN "input"
886 #endif
887
888
889 static void ag_diagnose(void) {
890 int ag_snd = (PCB).sn;
891 int ag_k = ag_sbt[ag_snd];
892
893 if (*TOKEN_NAMES[ag_tstt[ag_k]] && ag_astt[ag_k + 1] == ag_action_8) {
894 sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
895 }
896 else if (ag_astt[ag_sbe[(PCB).sn]] == ag_action_8
897 && (ag_k = (int) ag_sbe[(PCB).sn] + 1) == (int) ag_sbt[(PCB).sn+1] - 1
898 && *TOKEN_NAMES[ag_tstt[ag_k]]) {
899 sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
900 }
901 else if ((PCB).token_number && *TOKEN_NAMES[(PCB).token_number]) {
902 sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, TOKEN_NAMES[(PCB).token_number]);
903 }
904 else if (isprint(INPUT_CODE((*(PCB).pointer))) && INPUT_CODE((*(PCB).pointer)) != '\\') {
905 char buf[20];
906 sprintf(buf, "\'%c\'", (char) INPUT_CODE((*(PCB).pointer)));
907 sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, buf);
908 }
909 else sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, UNNAMED_TOKEN);
910 (PCB).error_message = (PCB).ag_msg;
911
912
913 }
914 static int ag_action_1_r_proc(void);
915 static int ag_action_2_r_proc(void);
916 static int ag_action_3_r_proc(void);
917 static int ag_action_4_r_proc(void);
918 static int ag_action_1_s_proc(void);
919 static int ag_action_3_s_proc(void);
920 static int ag_action_1_proc(void);
921 static int ag_action_2_proc(void);
922 static int ag_action_3_proc(void);
923 static int ag_action_4_proc(void);
924 static int ag_action_5_proc(void);
925 static int ag_action_6_proc(void);
926 static int ag_action_7_proc(void);
927 static int ag_action_8_proc(void);
928 static int ag_action_9_proc(void);
929 static int ag_action_10_proc(void);
930 static int ag_action_11_proc(void);
931 static int ag_action_8_proc(void);
932
933
934 static int (*const ag_r_procs_scan[])(void) = {
935 ag_action_1_r_proc,
936 ag_action_2_r_proc,
937 ag_action_3_r_proc,
938 ag_action_4_r_proc
939 };
940
941 static int (*const ag_s_procs_scan[])(void) = {
942 ag_action_1_s_proc,
943 ag_action_2_r_proc,
944 ag_action_3_s_proc,
945 ag_action_4_r_proc
946 };
947
948 static int (*const ag_gt_procs_scan[])(void) = {
949 ag_action_1_proc,
950 ag_action_2_proc,
951 ag_action_3_proc,
952 ag_action_4_proc,
953 ag_action_5_proc,
954 ag_action_6_proc,
955 ag_action_7_proc,
956 ag_action_8_proc,
957 ag_action_9_proc,
958 ag_action_10_proc,
959 ag_action_11_proc,
960 ag_action_8_proc
961 };
962
963
964 static int ag_action_10_proc(void) {
965 int ag_t = (PCB).token_number;
966 do {
967 (PCB).pointer = (PCB).la_ptr;
968 (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
969 (PCB).la_ptr++;
970 } while ((PCB).token_number == (mas_token_type) ag_t);
971 (PCB).la_ptr = (PCB).pointer;
972 return 1;
973 }
974
975 static int ag_action_11_proc(void) {
976 int ag_t = (PCB).token_number;
977
978 do {
979 (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
980 (PCB).ssx--;
981 (PCB).pointer = (PCB).la_ptr;
982 ag_ra();
983 if ((PCB).exit_flag != AG_RUNNING_CODE) return 0;
984 (PCB).ssx++;
985 (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
986 (PCB).la_ptr++;
987 }
988 while ((PCB).token_number == (mas_token_type) ag_t);
989 (PCB).la_ptr = (PCB).pointer;
990 return 1;
991 }
992
993 static int ag_action_3_r_proc(void) {
994 int ag_sd = ag_fl[(PCB).ag_ap] - 1;
995 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
996 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
997 ag_ra();
998 return (PCB).exit_flag == AG_RUNNING_CODE;
999 }
1000
1001 static int ag_action_3_s_proc(void) {
1002 int ag_sd = ag_fl[(PCB).ag_ap] - 1;
1003 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1004 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1005 ag_ra();
1006 return (PCB).exit_flag == AG_RUNNING_CODE;
1007 }
1008
1009 static int ag_action_4_r_proc(void) {
1010 int ag_sd = ag_fl[(PCB).ag_ap] - 1;
1011 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1012 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1013 return 1;
1014 }
1015
1016 static int ag_action_2_proc(void) {
1017 if ((PCB).ssx >= 128) {
1018 ag_trace_error();
1019 (PCB).exit_flag = AG_STACK_ERROR_CODE;
1020 PARSER_STACK_OVERFLOW;
1021 }
1022 (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
1023 (PCB).ss[(PCB).ssx] = (PCB).sn;
1024 (PCB).ssx++;
1025 (PCB).sn = (PCB).ag_ap;
1026 (PCB).pointer = (PCB).la_ptr;
1027 return 0;
1028 }
1029
1030 static int ag_action_9_proc(void) {
1031 if ((PCB).ssx >= 128) {
1032 ag_trace_error();
1033 (PCB).exit_flag = AG_STACK_ERROR_CODE;
1034 PARSER_STACK_OVERFLOW;
1035 }
1036 (PCB).vs[(PCB).ssx] = ag_null_value;
1037 (PCB).ss[(PCB).ssx] = (PCB).sn;
1038 (PCB).ssx++;
1039 (PCB).sn = (PCB).ag_ap;
1040 (PCB).la_ptr = (PCB).pointer;
1041 return (PCB).exit_flag == AG_RUNNING_CODE;
1042 }
1043
1044 static int ag_action_2_r_proc(void) {
1045 (PCB).ssx++;
1046 (PCB).sn = (PCB).ag_ap;
1047 return 0;
1048 }
1049
1050 static int ag_action_7_proc(void) {
1051 --(PCB).ssx;
1052 (PCB).la_ptr = (PCB).pointer;
1053 (PCB).exit_flag = AG_SUCCESS_CODE;
1054 return 0;
1055 }
1056
1057 static int ag_action_1_proc(void) {
1058 (PCB).pointer = (PCB).la_ptr;
1059 (PCB).exit_flag = AG_SUCCESS_CODE;
1060 return 0;
1061 }
1062
1063 static int ag_action_1_r_proc(void) {
1064 (PCB).exit_flag = AG_SUCCESS_CODE;
1065 return 0;
1066 }
1067
1068 static int ag_action_1_s_proc(void) {
1069 (PCB).exit_flag = AG_SUCCESS_CODE;
1070 return 0;
1071 }
1072
1073 static int ag_action_4_proc(void) {
1074 int ag_sd = ag_fl[(PCB).ag_ap] - 1;
1075 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1076 (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
1077 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1078 else (PCB).ss[(PCB).ssx] = (PCB).sn;
1079 (PCB).pointer = (PCB).la_ptr;
1080 while ((PCB).exit_flag == AG_RUNNING_CODE) {
1081 unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
1082 unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
1083 do {
1084 unsigned ag_tx = (ag_t1 + ag_t2)/2;
1085 if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
1086 else ag_t2 = ag_tx;
1087 } while (ag_t1 < ag_t2);
1088 if (ag_tstt[ag_t1] != (PCB).reduction_token) {
1089 (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
1090 REDUCTION_TOKEN_ERROR; break;}
1091 (PCB).ag_ap = ag_pstt[ag_t1];
1092 if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
1093 }
1094 return 0;
1095 }
1096
1097 static int ag_action_3_proc(void) {
1098 int ag_sd = ag_fl[(PCB).ag_ap] - 1;
1099 (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
1100 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1101 else (PCB).ss[(PCB).ssx] = (PCB).sn;
1102 (PCB).pointer = (PCB).la_ptr;
1103 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1104 ag_ra();
1105 while ((PCB).exit_flag == AG_RUNNING_CODE) {
1106 unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
1107 unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
1108 do {
1109 unsigned ag_tx = (ag_t1 + ag_t2)/2;
1110 if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
1111 else ag_t2 = ag_tx;
1112 } while (ag_t1 < ag_t2);
1113 if (ag_tstt[ag_t1] != (PCB).reduction_token) {
1114 (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
1115 REDUCTION_TOKEN_ERROR; break;}
1116 (PCB).ag_ap = ag_pstt[ag_t1];
1117 if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
1118 }
1119 return 0;
1120 }
1121
1122 static int ag_action_8_proc(void) {
1123 ag_trace_error();
1124 (PCB).la_ptr = (PCB).pointer;
1125 (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
1126 ag_diagnose();
1127 SYNTAX_ERROR;
1128 (PCB).la_ptr = ++(PCB).pointer;
1129 return (PCB).exit_flag == AG_RUNNING_CODE;
1130 }
1131
1132 static int ag_action_5_proc(void) {
1133 int ag_sd = ag_fl[(PCB).ag_ap];
1134 if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1135 else {
1136 (PCB).ss[(PCB).ssx] = (PCB).sn;
1137 }
1138 (PCB).la_ptr = (PCB).pointer;
1139 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1140 ag_ra();
1141 while ((PCB).exit_flag == AG_RUNNING_CODE) {
1142 unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
1143 unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
1144 do {
1145 unsigned ag_tx = (ag_t1 + ag_t2)/2;
1146 if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
1147 else ag_t2 = ag_tx;
1148 } while (ag_t1 < ag_t2);
1149 if (ag_tstt[ag_t1] != (PCB).reduction_token) {
1150 (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
1151 REDUCTION_TOKEN_ERROR; break;}
1152 (PCB).ag_ap = ag_pstt[ag_t1];
1153 if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
1154 }
1155 return (PCB).exit_flag == AG_RUNNING_CODE;
1156 }
1157
1158 static int ag_action_6_proc(void) {
1159 int ag_sd = ag_fl[(PCB).ag_ap];
1160 (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
1161 if (ag_sd) {
1162 (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
1163 }
1164 else {
1165 if ((PCB).ssx >= 128) {
1166 ag_trace_error();
1167 (PCB).exit_flag = AG_STACK_ERROR_CODE;
1168 PARSER_STACK_OVERFLOW;
1169 }
1170 (PCB).vs[(PCB).ssx] = ag_null_value;
1171 (PCB).ss[(PCB).ssx] = (PCB).sn;
1172 }
1173 (PCB).la_ptr = (PCB).pointer;
1174 while ((PCB).exit_flag == AG_RUNNING_CODE) {
1175 unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
1176 unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
1177 do {
1178 unsigned ag_tx = (ag_t1 + ag_t2)/2;
1179 if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
1180 else ag_t2 = ag_tx;
1181 } while (ag_t1 < ag_t2);
1182 if (ag_tstt[ag_t1] != (PCB).reduction_token) {
1183 (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
1184 REDUCTION_TOKEN_ERROR; break;}
1185 (PCB).ag_ap = ag_pstt[ag_t1];
1186 if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
1187 }
1188 return (PCB).exit_flag == AG_RUNNING_CODE;
1189 }
1190
1191
1192 void init_mas(void) {
1193 (PCB).la_ptr = (PCB).pointer;
1194 (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
1195 (PCB).exit_flag = AG_RUNNING_CODE;
1196 }
1197
1198 void mas(void) {
1199 init_mas();
1200 (PCB).exit_flag = AG_RUNNING_CODE;
1201 while ((PCB).exit_flag == AG_RUNNING_CODE) {
1202 unsigned ag_t1 = ag_sbt[(PCB).sn];
1203 if (ag_tstt[ag_t1]) {
1204 unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
1205 (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
1206 (PCB).la_ptr++;
1207 do {
1208 unsigned ag_tx = (ag_t1 + ag_t2)/2;
1209 if (ag_tstt[ag_tx] > (unsigned char)(PCB).token_number)
1210 ag_t1 = ag_tx + 1;
1211 else ag_t2 = ag_tx;
1212 } while (ag_t1 < ag_t2);
1213 if (ag_tstt[ag_t1] != (unsigned char)(PCB).token_number)
1214 ag_t1 = ag_sbe[(PCB).sn];
1215 }
1216 (PCB).ag_ap = ag_pstt[ag_t1];
1217 (ag_gt_procs_scan[ag_astt[ag_t1]])();
1218 }
1219 }
1220
1221