Mercurial > ~dholland > hg > ag > index.cgi
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 |