1
2 lalr_grammar_parser_: proc (db_sw, local_recoveries, skip_recoveries, code);
3
4
5
6 dcl code fixed bin (35) parameter;
7 dcl db_sw bit (1) parameter;
8
9 %include lalr_parse_grammar_t_;
10 dcl 1 stk (-4:100),
11
12
13 2 symptr ptr,
14 2 symlen fixed bin,
15 2 line_id aligned,
16 3 file fixed bin (17) unaligned,
17 3 line fixed bin (17) unaligned,
18 2 symbol fixed bin,
19 2 token_position fixed bin (21),
20 2 token_length fixed bin,
21 2 tag fixed bin;
22 dcl 1 lookahead (-4:100) defined stk like stk;
23 dcl abs builtin;
24 dcl current_state fixed bin;
25 dcl current_table fixed bin;
26 dcl 1 db_data unaligned,
27 2 flag char (1),
28 2 state picture "zzz9",
29 2 top picture "zzz9",
30 2 filler char (2),
31 2 type char (6),
32 2 data char (100);
33 dcl db_item char (117) defined (db_data);
34 dcl db_separator char (1);
35 dcl divide builtin;
36 dcl error_count fixed bin;
37
38
39
40 dcl false bit (1) internal static options (constant) init ("0"b);
41 dcl hbound builtin;
42 dcl i fixed bin;
43 dcl ioa_$nnl entry options (variable);
44
45
46 dcl lalr_error_table_$parser_logic_error fixed bin (35) external static;
47
48 dcl lalr_error_table_$parser_stack_overflow fixed bin (35) external static;
49
50 dcl lalr_error_table_$parser_syntax_error fixed bin (35) external static;
51
52 dcl lalr_error_table_$parser_unrecognized_state fixed bin (35) external static;
53 dcl lb fixed bin;
54 dcl lbound builtin;
55 dcl stk_top fixed bin defined parse_stack_top;
56 dcl local_recoveries fixed bin;
57 dcl lookahead_count fixed bin;
58 dcl lookahead_get fixed bin;
59 dcl lookahead_put fixed bin;
60 dcl next_state fixed bin;
61 dcl nil_symbol fixed bin;
62 dcl null builtin;
63 dcl parse_stack (100) fixed bin aligned;
64 dcl parse_stack_top fixed bin;
65 dcl parse_stack2 (100) fixed bin aligned;
66 dcl production_number fixed bin;
67 dcl read_count fixed bin;
68 dcl recov_msg char (250) varying;
69 dcl skip_recoveries fixed bin;
70 dcl t fixed bin;
71 dcl test_state fixed bin;
72 dcl test_symbol fixed bin defined test_state;
73 dcl true bit (1) internal static options (constant) init ("1"b);
74 dcl ub fixed bin;
75 dcl unspec builtin;
76 dcl zero fixed bin internal static options (constant) init (0);
77 %page;
78 current_state = 1;
79 parse_stack_top = 0;
80 lookahead_put, lookahead_get = -1;
81 if skip_size > 0 then
82 nil_symbol = skip.v1 (2);
83 else nil_symbol = 10000;
84 error_count = 0;
85 local_recoveries = 0;
86 skip_recoveries = 0;
87 lookahead_count = 0;
88 unspec (stk) = ""b;
89 code = 0;
90
91
92 NEXT:
93 if current_state = 0
94 then do;
95 parse_done:
96 return;
97 end;
98 current_table = current_state;
99 db_item = "";
100 db_data.state = current_state;
101 db_data.top = parse_stack_top;
102 go to CASE (dpda.v1 (current_table));
103
104 CASE (10):
105
106
107 CASE (2):
108
109
110
111 current_table = dpda.v2 (current_table);
112
113 CASE (0):
114
115 CASE (9):
116
117 CASE (15):
118
119 CASE (17):
120
121
122 if lookahead_count <= 0
123 then do;
124 call scanner;
125 if lookahead_put = lbound (lookahead, 1) then
126 lookahead_put = 0;
127 lookahead_put = lookahead_put - 1;
128 lookahead_count = lookahead_count + 1;
129 end;
130 test_symbol = lookahead.symbol (lookahead_get);
131
132 search_table:
133 lb = current_table + 1;
134 ub = current_table + dpda.v2 (current_table);
135 do while (lb <= ub);
136 i = divide (ub + lb, 2, 17, 0);
137 if dpda.v1 (i) = test_symbol
138 then do;
139 next_state = dpda.v2 (i);
140 go to got_symbol;
141 end;
142 else if dpda.v1 (i) < test_symbol then
143 lb = i + 1;
144 else ub = i - 1;
145 end;
146 if dpda.v1 (current_table + 1) < 0 then
147 if dpda.v1 (current_table + 1) = -1
148 then do;
149 current_state = -dpda.v2 (current_table + 1);
150 if db_sw
151 then do;
152 db_data.type = "LK01D";
153 db_data.data = get_terminal (lookahead_get);
154 call ioa_$nnl ("^a^/", db_item);
155 end;
156 go to NEXT;
157 end;
158 else do;
159 current_table = dpda.v2 (current_table + 1);
160 go to search_table;
161 end;
162
163 if error_count < 1 then
164 if local_recovered () then
165 go to NEXT;
166
167 if skip_size > 2
168 then do;
169 call skip_recovery;
170 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
171 go to NEXT;
172 end;
173
174 if db_sw then
175 call ioa_$nnl (" ^4i^/", current_state);
176 call set_line_id (lookahead_get, "FATAL");
177 recov_msg = recov_msg || "at ";
178 recov_msg = recov_msg || get_terminal (lookahead_get);
179 recov_msg = recov_msg || ".";
180 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
181 code = lalr_error_table_$parser_syntax_error;
182 go to parse_done;
183
184 got_symbol:
185 if db_sw then
186 db_data.data = get_terminal (lookahead_get);
187 if next_state < 0
188 then do;
189 db_data.type = "LK01";
190 current_state = -next_state;
191 end;
192 else do;
193 db_data.type = "READ";
194 db_data.flag = "*";
195 if error_count > 0 then
196 error_count = error_count - 1;
197 if parse_stack_top >= hbound (parse_stack, 1) then
198 call parse_stack_overflow;
199 parse_stack_top = parse_stack_top + 1;
200 parse_stack (parse_stack_top) = current_state;
201 unspec (stk (parse_stack_top)) = unspec (lookahead (lookahead_get));
202 if lookahead_get = lbound (lookahead, 1) then
203 lookahead_get = 0;
204 lookahead_get = lookahead_get - 1;
205 lookahead_count = lookahead_count - 1;
206 current_state = next_state;
207 end;
208 if db_sw then
209 call ioa_$nnl ("^a^/", db_item);
210 go to NEXT;
211
212 CASE (3):
213 CASE (1):
214 CASE (14):
215 CASE (16):
216
217
218 CASE (7):
219 CASE (8):
220
221 CASE (4):
222 CASE (5):
223 CASE (6):
224
225 CASE (18):
226 CASE (19):
227 CASE (20):
228 unrecognized_dpda_state:
229 if lookahead_count <= 0
230 then do;
231 call scanner;
232 if lookahead_put = lbound (lookahead, 1) then
233 lookahead_put = 0;
234 lookahead_put = lookahead_put - 1;
235 lookahead_count = 1;
236 end;
237 call set_line_id (lookahead_get, "LALR translator");
238 recov_msg = recov_msg || "Unrecognized DPDA state encountered
239 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
240 code = lalr_error_table_$parser_unrecognized_state;
241 go to parse_done;
242
243 CASE (13):
244 current_table = dpda.v2 (current_state + 2);
245 CASE (11):
246 CASE (12):
247 production_number = dpda.v1 (current_state + 2);
248 if production_number > 0 then
249 call lalr_grammar_semantics_ (production_number);
250
251 if db_sw
252 then do;
253 db_data.type = "APLY";
254 db_data.data = "(";
255 if dpda.v1 (current_state + 1) < 0 then
256 db_data.flag = "*";
257 call ioa_$nnl ("^a^i", db_item, production_number);
258 call print_production_name (production_number);
259 call ioa_$nnl (")^-sd = ^i ", dpda.v1 (current_state + 1));
260 if dpda.v1 (current_state + 1) > 0
261 then do;
262 db_separator = "(";
263 do t = parse_stack_top to parse_stack_top - dpda.v1 (current_state + 1) + 1 by -1;
264 call ioa_$nnl ("^1a^d", db_separator, parse_stack (t));
265 db_separator = "";
266 end;
267 call ioa_$nnl (")");
268 end;
269 call ioa_$nnl ("^/");
270 end;
271
272
273
274
275
276 if dpda.v1 (current_state + 1) < 0
277 then do;
278 if parse_stack_top >= hbound (parse_stack, 1) then
279 call parse_stack_overflow;
280 parse_stack (parse_stack_top + 1) = current_state;
281 end;
282
283 parse_stack_top = parse_stack_top - dpda.v1 (current_state + 1);
284 if parse_stack_top <= 0
285 then do;
286 if skip_recoveries > 0
287 then do;
288 call set_line_id (lookahead_get, "FATAL");
289 recov_msg = recov_msg
290 || "parser has lost its place due to failed skip recoveries.";
291 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
292 code = lalr_error_table_$parser_syntax_error;
293 end;
294 else do;
295 call set_line_id (lookahead_get, "LALR translator");
296 recov_msg = recov_msg || "lexical/parse stack empty
297 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
298 code = lalr_error_table_$parser_logic_error;
299 end;
300 go to parse_done;
301 end;
302 test_state = parse_stack (parse_stack_top);
303 lb = current_table + 3;
304 ub = current_table + dpda.v2 (current_table);
305 do while (lb <= ub);
306 i = divide (ub + lb, 2, 17, 0);
307 if dpda.v1 (i) = test_state
308 then do;
309 current_state = dpda.v2 (i);
310 go to NEXT;
311 end;
312 else if dpda.v1 (i) < test_state then
313 lb = i + 1;
314 else ub = i - 1;
315 end;
316 current_state = dpda.v2 (current_table + 2);
317 go to NEXT;
318 ^L
319 local_recovered: proc returns (bit (1));
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387 ^L
388 dcl best_alternate_symbol fixed bin;
389 dcl delete_B fixed bin internal static options (constant) init (2);
390 dcl combinations fixed bin;
391 dcl insert_before_B fixed bin internal static options (constant) init (3);
392 dcl lookahead_bad fixed bin;
393 dcl lookahead_last fixed bin;
394 dcl lookahead_last_read fixed bin;
395 dcl lookahead_next fixed bin;
396 dcl recovery_method fixed bin;
397 dcl replace_B fixed bin internal static options (constant) init (4);
398 dcl transit fixed bin;
399
400 if test_symbol < 0
401 then do;
402 call set_line_id (lookahead_get, "LALR translator");
403 recov_msg = recov_msg
404 || "negative terminal (invalid parser DPDA); cannot recover.";
405 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
406 return (false);
407 end;
408 do while (lookahead_count < 2);
409 call scanner;
410 if lookahead_put = lbound (lookahead, 1) then
411 lookahead_put = 0;
412 lookahead_put = lookahead_put - 1;
413 lookahead_count = lookahead_count + 1;
414 end;
415 if db_sw then
416 call dump_lookahead;
417
418 lookahead_bad = lookahead_get;
419 if lookahead_get = lbound (lookahead, 1) then
420 lookahead_next = -1;
421 else lookahead_next = lookahead_get - 1;
422 lookahead_last_read = lookahead_get + 1;
423 if lookahead_last_read = 0 then
424 lookahead_last_read = lbound (lookahead, 1);
425 lookahead_last = lookahead_get + 1;
426 if lookahead_last = 0 then
427 lookahead_last = lbound (lookahead, 1);
428
429 combinations = 0;
430
431 unspec (lookahead (0)) = unspec (lookahead (lookahead_bad));
432 unspec (lookahead (lookahead_bad)) = unspec (lookahead (lookahead_next));
433 unspec (lookahead (lookahead_next)) = unspec (lookahead (0));
434 if db_sw then
435 call ioa_$nnl ("#^- Reversing B and N.^/");
436 call trial_parse (parse_stack_top, lookahead_get, 3);
437 if read_count = 3 then
438 combinations, recovery_method = 1;
439 unspec (lookahead (lookahead_next)) = unspec (lookahead (lookahead_bad));
440 unspec (lookahead (lookahead_bad)) = unspec (lookahead (0));
441
442 lookahead_count = lookahead_count - 1;
443 if db_sw then
444 call ioa_$nnl ("#^- Deleting B.^/");
445 call trial_parse (parse_stack_top, lookahead_next, 2);
446 if read_count = 2
447 then do;
448 if combinations = 0 then
449 recovery_method = delete_B;
450 combinations = combinations + 1;
451 end;
452 lookahead_count = lookahead_count + 1;
453 if combinations < 2
454 then do;
455
456 lookahead_count = lookahead_count + 1;
457 lookahead.symlen (lookahead_last_read) = 0;
458 if db_sw then
459 call ioa_$nnl ("#^- Inserting alternate symbols before B.^/");
460 call try_alternatives (insert_before_B);
461 lookahead_count = lookahead_count - 1;
462 if combinations = 2 & recovery_method = delete_B then
463 if best_alternate_symbol < lookahead.symbol (0)
464 then do;
465 recovery_method = insert_before_B;
466 transit = best_alternate_symbol;
467 end;
468 end;
469
470 if combinations < 2
471 then do;
472
473 lookahead.symlen (lookahead_bad) = 0;
474 if db_sw then
475 call ioa_$nnl ("#^- Replacing B with alternate symbols.^/");
476 call try_alternatives (replace_B);
477 unspec (lookahead (lookahead_bad)) = unspec (lookahead (0));
478 end;
479
480 if combinations = 0 then
481 return (false);
482 call set_line_id (lookahead_bad, "WARNING");
483 go to case (recovery_method);
484
485 case (1):
486 unspec (lookahead (lookahead_bad)) = unspec (lookahead (lookahead_next));
487 unspec (lookahead (lookahead_next)) = unspec (lookahead (0));
488 recov_msg = recov_msg || get_terminal (lookahead_next);
489 recov_msg = recov_msg || " and ";
490 recov_msg = recov_msg || get_terminal (lookahead_bad);
491 recov_msg = recov_msg || " are reversed";
492 go to done;
493
494 case (2):
495 lookahead_get = lookahead_next;
496 lookahead_count = lookahead_count - 1;
497 error_count = error_count - 1;
498 recov_msg = recov_msg || "extraneous ";
499 recov_msg = recov_msg || get_terminal (zero);
500 recov_msg = recov_msg || " before ";
501 recov_msg = recov_msg || get_terminal (lookahead_next);
502 recov_msg = recov_msg || " ignored";
503 go to done;
504
505 case (3):
506 lookahead.symbol (lookahead_last_read) = transit;
507 lookahead.symlen (lookahead_last_read) = 0;
508 lookahead_get = lookahead_last_read;
509 lookahead_count = lookahead_count + 1;
510 error_count = error_count + 1;
511 recov_msg = recov_msg || "missing ";
512 recov_msg = recov_msg || get_terminal (lookahead_last_read);
513 recov_msg = recov_msg || " is assumed before ";
514 recov_msg = recov_msg || get_terminal (lookahead_bad);
515 go to done;
516
517 case (4):
518 lookahead.symbol (lookahead_bad) = transit;
519 lookahead.symlen (lookahead_bad) = 0;
520 recov_msg = recov_msg || get_terminal (lookahead_bad);
521 recov_msg = recov_msg || " substituted for erroneous ";
522 recov_msg = recov_msg || get_terminal (zero);
523
524 done:
525 local_recoveries = local_recoveries + 1;
526 error_count = error_count + 4;
527 if combinations > 1 then
528 recov_msg = recov_msg || " (other diagnoses are possible)";
529 recov_msg = recov_msg || ".";
530 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
531 if db_sw then
532 call dump_lookahead;
533 return (true);
534 ^L
535 dump_lookahead: proc;
536 dcl i fixed bin;
537 if db_sw
538 then do;
539 do i = lookahead_get repeat i - 1 while (i ^= lookahead_put);
540 call ioa_$nnl ("#la (^i) ^3i ^a^/", i, lookahead.symbol (i), get_terminal (i));
541 if i = lbound (lookahead, 1) then
542 i = 0;
543 end;
544 end;
545 end dump_lookahead;
546 %page;
547 try_alternatives: proc (method);
548 dcl alternate_lookahead_get fixed bin;
549 dcl alternate_symbol fixed bin;
550 dcl method fixed bin parameter;
551 dcl min builtin;
552 dcl read_limit fixed bin;
553 dcl repair_loc fixed bin;
554 dcl repair_type char (10);
555 if method = insert_before_B
556 then do;
557 alternate_lookahead_get = lookahead_last_read;
558 read_limit = 4;
559 repair_loc = lookahead_last_read;
560 repair_type = "INSERT";
561 end;
562 else do;
563 alternate_lookahead_get = lookahead_get;
564 read_limit = 3;
565 repair_loc = lookahead_bad;
566 repair_type = "SUBSTITUTE";
567 end;
568 best_alternate_symbol = 10000;
569
570
571 current_table = current_state;
572 if dpda.v1 (current_table) = 2 then
573 current_table = dpda.v2 (current_table);
574 search_table:
575 do i = current_table + 1 to current_table + dpda.v2 (current_table)
576 while (combinations < 2);
577 alternate_symbol = dpda.v1 (i);
578 if alternate_symbol < nil_symbol & alternate_symbol ^= 0
579 then do;
580 lookahead.symbol (repair_loc) = alternate_symbol;
581 if db_sw then
582 call ioa_$nnl ("#^- ^a ^a^/", repair_type, get_terminal (repair_loc));
583 call trial_parse (parse_stack_top, alternate_lookahead_get, read_limit);
584 if read_count = read_limit
585 then do;
586 best_alternate_symbol = min (best_alternate_symbol, alternate_symbol);
587 if combinations = 0
588 then do;
589 recovery_method = method;
590 transit = alternate_symbol;
591 end;
592 combinations = combinations + 1;
593 end;
594 end;
595 end;
596 if dpda.v1 (current_table + 1) = -2
597 then do;
598 current_table = dpda.v2 (current_table + 1);
599 go to search_table;
600 end;
601 return;
602 end try_alternatives;
603 end local_recovered;
604 ^L
605 skip_recovery: proc;
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642 Note
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726 ^L
727 dcl c fixed bin;
728 dcl (i, ii) fixed bin;
729 dcl (j, jj) fixed bin;
730 dcl k fixed bin;
731 dcl lookahead_get2 fixed bin;
732 dcl lookahead_last fixed bin;
733
734 skip_recoveries = skip_recoveries + 1;
735 if parse_stack_top >= hbound (parse_stack, 1) then
736 call parse_stack_overflow;
737 parse_stack_top = parse_stack_top + 1;
738 parse_stack (parse_stack_top) = current_state;
739 unspec (stk (parse_stack_top)) = unspec (lookahead (lookahead_get));
740 call set_line_id (lookahead_get, "FATAL");
741 recov_msg = recov_msg || get_terminal (lookahead_get);
742 recov_msg = recov_msg || " appears out of context";
743 if lookahead.symbol (lookahead_get) = 0 then
744 go to assume_final_state;
745 recov_msg = recov_msg || ". Skipped";
746 if db_sw
747 then do i = parse_stack_top by -1 while (i > 0);
748 call ioa_$nnl ("@ps (^2i) ^4i^/", i, parse_stack (i));
749 end;
750 c = lookahead.symbol (lookahead_get);
751 do while (c ^= 0);
752 if lookahead_count <= 0
753 then do;
754 call scanner;
755 if lookahead_put = lbound (lookahead, 1) then
756 lookahead_put = 0;
757 lookahead_put = lookahead_put - 1;
758 lookahead_count = 1;
759 end;
760 c = lookahead.symbol (lookahead_get);
761 if db_sw then
762 call ioa_$nnl ("@ SKIP ^a^/", get_terminal (lookahead_get));
763 unspec (lookahead (0)) = unspec (lookahead (lookahead_get));
764 lookahead.symbol (lookahead_get) = nil_symbol;
765 lookahead.symlen (lookahead_get) = 0;
766 lookahead_last = lookahead_get;
767 if lookahead_get = lbound (lookahead, 1) then
768 lookahead_get = 0;
769 lookahead_get = lookahead_get - 1;
770 lookahead_count = lookahead_count - 1;
771 do i = 3 to 1 + skip.v2 (1);
772 if skip.v1 (i) = c
773 then do;
774 jj = skip.v2 (i);
775 do j = parse_stack_top to 1 by -1;
776 do ii = jj + 1 to jj + skip.v2 (jj);
777 if skip.v1 (ii) = parse_stack (j)
778 then do;
779 new_trial_parse:
780 lookahead_get2 = lookahead_get;
781 current_state = skip.v2 (ii);
782 call trial_parse (j - 1, lookahead_get2, 2);
783 if read_count < 2
784 then do;
785
786 lookahead_count = lookahead_count + 1;
787 lookahead_get2 = lookahead_last;
788 call trial_parse (j - 1, lookahead_get2, 2);
789 end;
790
791 if read_count >= 2
792 then do;
793 if db_sw
794 then do;
795 call ioa_$nnl ("@ ^4d ADJ sd = ^d ",
796 parse_stack_top, parse_stack_top - j + 1);
797 if parse_stack_top > j
798 then do;
799 db_separator = "(";
800 do jj = parse_stack_top to j by -1;
801 call ioa_$nnl ("^1a^d", db_separator, parse_stack (jj));
802 db_separator = "";
803 end;
804 call ioa_$nnl (")");
805 end;
806 call ioa_$nnl ("^/");
807 end;
808 parse_stack_top = j - 1;
809 lookahead_get = lookahead_get2;
810 recov_msg = recov_msg || " from ";
811 recov_msg = recov_msg || get_terminal (j);
812 recov_msg = recov_msg || " on ";
813 call append_line_id (j);
814 recov_msg = recov_msg || " to ";
815 recov_msg = recov_msg || get_terminal (zero);
816 if c ^= 0
817 then do;
818 recov_msg = recov_msg || " on ";
819 call append_line_id (zero);
820 end;
821 go to skip_exit;
822 end;
823 end;
824 end;
825 end;
826 end;
827 end;
828 end;
829 recov_msg = recov_msg || " to end-of-information";
830 assume_final_state:
831 current_state = 0;
832 skip_exit:
833 recov_msg = recov_msg || ".";
834 return;
835 end skip_recovery;
836 ^L
837 trial_parse: proc (parse_stack_top_parameter, lookahead_get_parameter, read_limit);
838 dcl current_table fixed bin;
839 dcl i fixed bin;
840 dcl lookahead_get fixed bin init (lookahead_get_parameter);
841 dcl lookahead_get_parameter fixed bin parameter;
842 dcl parse_stack_top fixed bin init (parse_stack_top_parameter);
843 dcl parse_stack_top_parameter fixed bin parameter;
844 dcl read_limit fixed bin parameter;
845 dcl trial_current_state fixed bin init (current_state);
846 parse_stack2 = parse_stack;
847 read_count = 0;
848 NEXT:
849 if trial_current_state = 0
850 then do;
851 read_count = read_limit;
852 return;
853 end;
854 db_item = "\";
855 db_data.state = trial_current_state;
856 db_data.top = parse_stack_top;
857 current_table = trial_current_state;
858 go to CASE (dpda.v1 (trial_current_state));
859
860 CASE (2):
861
862
863
864 CASE (10):
865
866 current_table = dpda.v2 (trial_current_state);
867 CASE (0):
868
869 CASE (9):
870
871 CASE (15):
872
873 CASE (17):
874
875
876
877 do while (lookahead_count <= read_count);
878 call scanner;
879 if lookahead_put = lbound (lookahead, 1) then
880 lookahead_put = 0;
881 lookahead_put = lookahead_put - 1;
882 lookahead_count = lookahead_count + 1;
883 end;
884 test_symbol = lookahead.symbol (lookahead_get);
885 search_table:
886
887 lb = current_table + 1;
888 ub = current_table + dpda.v2 (current_table);
889 do while (lb <= ub);
890 i = divide (ub + lb, 2, 17, 0);
891 if dpda.v1 (i) = test_symbol
892 then do;
893 next_state = dpda.v2 (i);
894 go to got_symbol;
895 end;
896 else if dpda.v1 (i) < test_symbol then
897 lb = i + 1;
898 else ub = i - 1;
899 end;
900 if dpda.v1 (current_table + 1) < 0 then
901 if dpda.v1 (current_table + 1) = -1
902 then do;
903 trial_current_state = -dpda.v2 (current_table + 1);
904 if db_sw
905 then do;
906 db_data.type = "LK01D";
907 db_data.data = get_terminal (lookahead_get);
908 call ioa_$nnl ("^a^/", db_item);
909 end;
910 go to NEXT;
911 end;
912 else do;
913 current_table = dpda.v2 (current_table + 1);
914 go to search_table;
915 end;
916 return;
917
918 got_symbol:
919 if db_sw
920 then do;
921 if next_state < 0
922 then do;
923 db_data.type = "LK01";
924 end;
925 else db_data.type = "READ";
926 db_data.data = get_terminal (lookahead_get);
927 call ioa_$nnl ("^a^/", db_item);
928 end;
929 if next_state < 0
930 then do;
931 trial_current_state = -next_state;
932 go to NEXT;
933 end;
934 else do;
935 read_count = read_count + 1;
936 if read_count < read_limit
937 then do;
938 if parse_stack_top >= hbound (stk, 1) then
939 call parse_stack_overflow;
940 parse_stack_top = parse_stack_top + 1;
941
942 parse_stack2 (parse_stack_top) = trial_current_state;
943 if lookahead_get = lbound (lookahead, 1) then
944 lookahead_get = 0;
945 lookahead_get = lookahead_get - 1;
946 trial_current_state = next_state;
947 go to NEXT;
948 end;
949 return;
950 end;
951
952 CASE (3):
953 CASE (1):
954 CASE (14):
955 CASE (16):
956
957 CASE (7):
958 CASE (8):
959
960 CASE (4):
961 CASE (5):
962 CASE (6):
963
964 CASE (18):
965 CASE (19):
966 CASE (20):
967 go to unrecognized_dpda_state;
968
969 CASE (13):
970 current_table = dpda.v2 (trial_current_state + 2);
971 CASE (11):
972 CASE (12):
973 production_number = dpda.v1 (trial_current_state + 2);
974
975 if db_sw
976 then do;
977 db_data.type = "APLY";
978 db_data.data = "(";
979 call ioa_$nnl ("^a^i", db_item, production_number);
980 call print_production_name (production_number);
981 call ioa_$nnl (")^-sd = ^i ", dpda.v1 (trial_current_state + 1));
982 if dpda.v1 (trial_current_state + 1) > 0
983 then do;
984 db_separator = "(";
985 do t = parse_stack_top to parse_stack_top - dpda.v1 (trial_current_state + 1) + 1 by -1;
986 call ioa_$nnl ("^1a^d", db_separator, parse_stack (t));
987 db_separator = "";
988 end;
989 call ioa_$nnl (")");
990 end;
991 call ioa_$nnl ("^/");
992 end;
993
994
995
996
997
998 if dpda.v1 (trial_current_state + 1) < 0
999 then do;
1000 if parse_stack_top >= hbound (parse_stack2, 1) then
1001 call parse_stack_overflow;
1002 parse_stack2 (parse_stack_top + 1) = trial_current_state;
1003 end;
1004 parse_stack_top = parse_stack_top - dpda.v1 (trial_current_state + 1);
1005 if parse_stack_top > 0
1006 then do;
1007 do i = current_table + 3 to current_table + dpda.v2 (current_table);
1008 if dpda.v1 (i) = parse_stack2 (parse_stack_top)
1009 then do;
1010 trial_current_state = dpda.v2 (i);
1011 go to NEXT;
1012 end;
1013 end;
1014 trial_current_state = dpda.v2 (current_table + 2);
1015 go to NEXT;
1016 end;
1017 return;
1018 end trial_parse;
1019 ^L
1020 get_terminal: proc (stk_index) returns (char (100) varying);
1021
1022 dcl stk_index fixed bin parameter;
1023 dcl alphanumeric (0:511) bit (1) unaligned internal static options (constant) init (
1024 (32) (1)"0"b,
1025 (4) (1)"0"b,
1026 "1"b,
1027 (11) (1)"0"b,
1028 (10) (1)"1"b,
1029 (7) (1)"0"b,
1030 (26) (1)"1"b,
1031 (4) (1)"0"b,
1032 "1"b,
1033 "0"b,
1034 (26) (1)"1"b,
1035 (5) (1)"0"b,
1036 (384) (1)"0"b);
1037 dcl temp char (100) varying;
1038 dcl (length, min, rank, substr) builtin;
1039
1040 if stk.symbol (stk_index) = 0 then
1041 return ("end-of-information");
1042 else begin;
1043 dcl symbol char (min (50, stk.symlen (stk_index))) based (stk.symptr (stk_index));
1044 dcl terminal char (terminals_list.length (stk.symbol (stk_index)))
1045 defined (terminal_characters) position (terminals_list.position (stk.symbol (stk_index)));
1046 if length (terminal) > 2
1047 & substr (terminal, 1, 1) = "<"
1048 & substr (terminal, length (terminal), 1) = ">"
1049 then do;
1050 temp = substr (terminal, 2, length (terminal) - 2);
1051 if length (symbol) > 0
1052 then do;
1053 temp = temp || " ";
1054 if substr (symbol, 1, 1) = """" | substr (symbol, 1, 1) = "'" then
1055 temp = temp || symbol;
1056 else do;
1057 temp = temp || """";
1058 temp = temp || symbol;
1059 temp = temp || """";
1060 end;
1061 end;
1062 end;
1063 else if alphanumeric (rank (substr (terminal, 1, 1)))
1064 then do;
1065 temp = "reserved word """;
1066 if length (symbol) > 0 then
1067 temp = temp || symbol;
1068 else temp = temp || terminal;
1069 temp = temp || """";
1070 end;
1071 else do;
1072 temp = "operator symbol """;
1073 temp = temp || terminal;
1074 temp = temp || """";
1075 end;
1076 return (temp);
1077 end;
1078 end get_terminal;
1079 ^L
1080 print_production_name: proc (production_name_index);
1081 dcl production_name_index fixed bin parameter;
1082 dcl variables_list_index fixed bin;
1083
1084 if production_names_size > 0
1085 then do;
1086 variables_list_index = -production_names (abs (production_name_index));
1087 begin;
1088 dcl production_name char (variables_list.length (variables_list_index))
1089 defined (variable_characters) position (variables_list.position (variables_list_index));
1090 call ioa_$nnl (" ^a", production_name);
1091 end;
1092 end;
1093 return;
1094 end print_production_name;
1095 ^L
1096 %include lalr_grammar_scanner_;
1097 %page;
1098 %include lalr_grammar_semantics_;
1099 %page;
1100 parse_stack_overflow: proc;
1101 dcl ltrim builtin;
1102 dcl omega picture "zzzzz9";
1103 omega = hbound (stk, 1);
1104 call set_line_id (lookahead_get, "FATAL");
1105 recov_msg = recov_msg || "exceeded ";
1106 recov_msg = recov_msg || ltrim (omega);
1107 recov_msg = recov_msg || " entries of the parser's lexical/parse stack. Parser cannot continue.";
1108 call lalr_print_ (static_data_ptr, "Un", "n", recov_msg);
1109 code = lalr_error_table_$parser_stack_overflow;
1110 go to parse_done;
1111 end parse_stack_overflow;
1112
1113
1114 append_line_id: proc (lookahead_use);
1115
1116 dcl lookahead_use fixed bin parameter;
1117 dcl omega picture "
1118 dcl setting_line_id bit (1);
1119 dcl severity char (*) parameter;
1120
1121 dcl ltrim builtin;
1122
1123 recov_msg = recov_msg || "line ";
1124 setting_line_id = "0"b;
1125 go to append_line_number;
1126 set_line_id: entry (lookahead_use, severity);
1127 recov_msg = severity;
1128 recov_msg = recov_msg || " error on line ";
1129 setting_line_id = "1"b;
1130 append_line_number:
1131 if stk.file (lookahead_use) ^= 0
1132 then do;
1133 omega = stk.file (lookahead_use);
1134 recov_msg = recov_msg || ltrim (omega);
1135 recov_msg = recov_msg || "-";
1136 end;
1137 omega = stk.line (lookahead_use);
1138 recov_msg = recov_msg || ltrim (omega);
1139 if setting_line_id then
1140 recov_msg = recov_msg || ": ";
1141 return;
1142 end append_line_id;
1143 %page;
1144 end lalr_grammar_parser_;