gcc config
[prop.git] / prop-src / parsegen.cc
blob3d29a4122b9fce670db1fc39a144c08d56e4cfb9
1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.6),
3 // last updated on Nov 2, 1999.
4 // The original source file is "parsegen.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_QUARK_USED
8 #include <propdefs.h>
9 ///////////////////////////////////////////////////////////////////////////////
10 // Quark literals
11 ///////////////////////////////////////////////////////////////////////////////
12 static const Quark _p_a_r_s_e_g_e_nco_c_c_Q1("'");
13 #line 1 "parsegen.pcc"
14 ///////////////////////////////////////////////////////////////////////////////
16 // This file implements the syntax/syntax class constructs of Prop.
18 ///////////////////////////////////////////////////////////////////////////////
19 #include <iostream>
20 #include <AD/strings/charesc.h>
21 #include <AD/strings/quark.h>
22 #include <AD/automata/grammar.h>
23 #include <AD/automata/operprec.h>
24 #include <AD/automata/lalr1gen.h>
25 #include "ir.h"
26 #include "ast.h"
27 #include "parsegen.h"
28 #include "datagen.h"
29 #include "hashtab.h"
30 #include "type.h"
31 #include "list.h"
32 #include "options.h"
34 ///////////////////////////////////////////////////////////////////////////////
36 // Instantiate the parser/grammar related datatypes
38 ///////////////////////////////////////////////////////////////////////////////
39 #line 26 "parsegen.pcc"
40 #line 26 "parsegen.pcc"
41 ///////////////////////////////////////////////////////////////////////////////
43 // Interface specification of datatype GramExp
45 ///////////////////////////////////////////////////////////////////////////////
46 #line 26 "parsegen.pcc"
49 ///////////////////////////////////////////////////////////////////////////////
51 // Interface specification of datatype List<GramExp>
53 ///////////////////////////////////////////////////////////////////////////////
54 #line 26 "parsegen.pcc"
57 ///////////////////////////////////////////////////////////////////////////////
59 // Interface specification of datatype BNF
61 ///////////////////////////////////////////////////////////////////////////////
62 #line 26 "parsegen.pcc"
65 ///////////////////////////////////////////////////////////////////////////////
67 // Interface specification of datatype List<BNF>
69 ///////////////////////////////////////////////////////////////////////////////
70 #line 26 "parsegen.pcc"
73 ///////////////////////////////////////////////////////////////////////////////
75 // Interface specification of datatype ProductionSymbol
77 ///////////////////////////////////////////////////////////////////////////////
78 #line 26 "parsegen.pcc"
81 ///////////////////////////////////////////////////////////////////////////////
83 // Interface specification of datatype List<ProductionSymbol>
85 ///////////////////////////////////////////////////////////////////////////////
86 #line 26 "parsegen.pcc"
89 ///////////////////////////////////////////////////////////////////////////////
91 // Interface specification of datatype PrecRule
93 ///////////////////////////////////////////////////////////////////////////////
94 #line 26 "parsegen.pcc"
97 ///////////////////////////////////////////////////////////////////////////////
99 // Interface specification of datatype List<PrecRule>
101 ///////////////////////////////////////////////////////////////////////////////
102 #line 26 "parsegen.pcc"
105 ///////////////////////////////////////////////////////////////////////////////
107 // Interface specification of datatype List<a_List<ProductionSymbol> * >
109 ///////////////////////////////////////////////////////////////////////////////
110 #line 26 "parsegen.pcc"
113 ///////////////////////////////////////////////////////////////////////////////
115 // Instantiation of datatype GramExp
117 ///////////////////////////////////////////////////////////////////////////////
118 #line 26 "parsegen.pcc"
119 GramExp_EXPgram::GramExp_EXPgram (a_List<PrecRule> * x_1, ShiftReduceErrors x_2, a_List<BNF> * x_3)
120 : a_GramExp(tag_EXPgram), _1(x_1), _2(x_2), _3(x_3)
123 a_GramExp * EXPgram (a_List<PrecRule> * x_1, ShiftReduceErrors x_2, a_List<BNF> * x_3)
125 return new GramExp_EXPgram (x_1, x_2, x_3);
127 GramExp_POLYgram::GramExp_POLYgram (int x_1, Id * x_2, GramExp x_3)
128 : a_GramExp(tag_POLYgram), _1(x_1), _2(x_2), _3(x_3)
131 a_GramExp * POLYgram (int x_1, Id * x_2, GramExp x_3)
133 return new GramExp_POLYgram (x_1, x_2, x_3);
135 GramExp_UNIONgram::GramExp_UNIONgram (GramExp x_1, GramExp x_2)
136 : a_GramExp(tag_UNIONgram), _1(x_1), _2(x_2)
139 a_GramExp * UNIONgram (GramExp x_1, GramExp x_2)
141 return new GramExp_UNIONgram (x_1, x_2);
143 GramExp_RESTRICTgram::GramExp_RESTRICTgram (GramExp x_RESTRICTgram)
144 : a_GramExp(tag_RESTRICTgram), RESTRICTgram(x_RESTRICTgram)
147 a_GramExp * RESTRICTgram (GramExp x_RESTRICTgram)
149 return new GramExp_RESTRICTgram (x_RESTRICTgram);
151 GramExp_APPgram::GramExp_APPgram (GramExp x_1, GramExp x_2)
152 : a_GramExp(tag_APPgram), _1(x_1), _2(x_2)
155 a_GramExp * APPgram (GramExp x_1, GramExp x_2)
157 return new GramExp_APPgram (x_1, x_2);
161 ///////////////////////////////////////////////////////////////////////////////
163 // Instantiation of datatype List<GramExp>
165 ///////////////////////////////////////////////////////////////////////////////
166 #line 26 "parsegen.pcc"
167 #ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION
168 template class a_List<GramExp>;
169 template a_List<GramExp> * list_1_(a_List<ProductionSymbol> * x_1, a_List<a_List<ProductionSymbol> * > * x_2);
170 template a_List<GramExp> * list_1_(a_List<ProductionSymbol> * x_list_1_);
171 template int boxed(const a_List<GramExp> *);
172 template int untag(const a_List<GramExp> *);
173 #endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */
175 ///////////////////////////////////////////////////////////////////////////////
177 // Instantiation of datatype BNF
179 ///////////////////////////////////////////////////////////////////////////////
180 #line 26 "parsegen.pcc"
181 a_BNF::a_BNF (Id x_1, Ty x_2, a_List<ProductionSymbols> * x_3)
182 : _1(x_1), _2(x_2), _3(x_3)
185 a_BNF * BNFrule (Id x_1, Ty x_2, a_List<ProductionSymbols> * x_3)
187 return new a_BNF (x_1, x_2, x_3);
191 ///////////////////////////////////////////////////////////////////////////////
193 // Instantiation of datatype List<BNF>
195 ///////////////////////////////////////////////////////////////////////////////
196 #line 26 "parsegen.pcc"
197 #ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION
198 template class a_List<BNF>;
199 template a_List<BNF> * list_1_(GramExp x_1, a_List<GramExp> * x_2);
200 template a_List<BNF> * list_1_(GramExp x_list_1_);
201 template int boxed(const a_List<BNF> *);
202 template int untag(const a_List<BNF> *);
203 #endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */
205 ///////////////////////////////////////////////////////////////////////////////
207 // Instantiation of datatype ProductionSymbol
209 ///////////////////////////////////////////////////////////////////////////////
210 #line 26 "parsegen.pcc"
211 ProductionSymbol_TERMsym::ProductionSymbol_TERMsym (char x_TERMsym)
212 : a_ProductionSymbol(tag_TERMsym), TERMsym(x_TERMsym)
215 a_ProductionSymbol * TERMsym (char x_TERMsym)
217 return new ProductionSymbol_TERMsym (x_TERMsym);
219 ProductionSymbol_TERMSTRINGsym::ProductionSymbol_TERMSTRINGsym (char const * x_TERMSTRINGsym)
220 : a_ProductionSymbol(tag_TERMSTRINGsym), TERMSTRINGsym(x_TERMSTRINGsym)
223 a_ProductionSymbol * TERMSTRINGsym (char const * x_TERMSTRINGsym)
225 return new ProductionSymbol_TERMSTRINGsym (x_TERMSTRINGsym);
227 ProductionSymbol_TERMREGEXPsym::ProductionSymbol_TERMREGEXPsym (char const * x_TERMREGEXPsym)
228 : a_ProductionSymbol(tag_TERMREGEXPsym), TERMREGEXPsym(x_TERMREGEXPsym)
231 a_ProductionSymbol * TERMREGEXPsym (char const * x_TERMREGEXPsym)
233 return new ProductionSymbol_TERMREGEXPsym (x_TERMREGEXPsym);
235 ProductionSymbol_TOKENsym::ProductionSymbol_TOKENsym (Cons x_TOKENsym)
236 : a_ProductionSymbol(tag_TOKENsym), TOKENsym(x_TOKENsym)
239 a_ProductionSymbol * TOKENsym (Cons x_TOKENsym)
241 return new ProductionSymbol_TOKENsym (x_TOKENsym);
243 ProductionSymbol_NONTERMsym::ProductionSymbol_NONTERMsym (Id x_NONTERMsym)
244 : a_ProductionSymbol(tag_NONTERMsym), NONTERMsym(x_NONTERMsym)
247 a_ProductionSymbol * NONTERMsym (Id x_NONTERMsym)
249 return new ProductionSymbol_NONTERMsym (x_NONTERMsym);
251 ProductionSymbol_POSNONTERMsym::ProductionSymbol_POSNONTERMsym (int x_POSNONTERMsym)
252 : a_ProductionSymbol(tag_POSNONTERMsym), POSNONTERMsym(x_POSNONTERMsym)
255 a_ProductionSymbol * POSNONTERMsym (int x_POSNONTERMsym)
257 return new ProductionSymbol_POSNONTERMsym (x_POSNONTERMsym);
259 ProductionSymbol_ACTIONsym::ProductionSymbol_ACTIONsym (a_List<Decl> * x_ACTIONsym)
260 : a_ProductionSymbol(tag_ACTIONsym), ACTIONsym(x_ACTIONsym)
263 a_ProductionSymbol * ACTIONsym (a_List<Decl> * x_ACTIONsym)
265 return new ProductionSymbol_ACTIONsym (x_ACTIONsym);
267 ProductionSymbol_PREDICATEsym::ProductionSymbol_PREDICATEsym (Exp x_PREDICATEsym)
268 : a_ProductionSymbol(tag_PREDICATEsym), PREDICATEsym(x_PREDICATEsym)
271 a_ProductionSymbol * PREDICATEsym (Exp x_PREDICATEsym)
273 return new ProductionSymbol_PREDICATEsym (x_PREDICATEsym);
275 ProductionSymbol_PRECsym::ProductionSymbol_PRECsym (Cons x_PRECsym)
276 : a_ProductionSymbol(tag_PRECsym), PRECsym(x_PRECsym)
279 a_ProductionSymbol * PRECsym (Cons x_PRECsym)
281 return new ProductionSymbol_PRECsym (x_PRECsym);
283 ProductionSymbol_ERRORsym::ProductionSymbol_ERRORsym ()
284 : a_ProductionSymbol(tag_ERRORsym)
287 a_ProductionSymbol * ERRORsym ()
289 return new ProductionSymbol_ERRORsym ;
291 ProductionSymbol_SPECIALsym::ProductionSymbol_SPECIALsym (char x_SPECIALsym)
292 : a_ProductionSymbol(tag_SPECIALsym), SPECIALsym(x_SPECIALsym)
295 a_ProductionSymbol * SPECIALsym (char x_SPECIALsym)
297 return new ProductionSymbol_SPECIALsym (x_SPECIALsym);
301 ///////////////////////////////////////////////////////////////////////////////
303 // Instantiation of datatype List<ProductionSymbol>
305 ///////////////////////////////////////////////////////////////////////////////
306 #line 26 "parsegen.pcc"
307 #ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION
308 template class a_List<ProductionSymbol>;
309 template a_List<ProductionSymbol> * list_1_(BNF x_1, a_List<BNF> * x_2);
310 template a_List<ProductionSymbol> * list_1_(BNF x_list_1_);
311 template int boxed(const a_List<ProductionSymbol> *);
312 template int untag(const a_List<ProductionSymbol> *);
313 #endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */
315 ///////////////////////////////////////////////////////////////////////////////
317 // Instantiation of datatype PrecRule
319 ///////////////////////////////////////////////////////////////////////////////
320 #line 26 "parsegen.pcc"
321 a_PrecRule::a_PrecRule (PrecMode x_1, int x_2, ProductionSymbols x_3)
322 : _1(x_1), _2(x_2), _3(x_3)
325 a_PrecRule * PRECrule (PrecMode x_1, int x_2, ProductionSymbols x_3)
327 return new a_PrecRule (x_1, x_2, x_3);
331 ///////////////////////////////////////////////////////////////////////////////
333 // Instantiation of datatype List<PrecRule>
335 ///////////////////////////////////////////////////////////////////////////////
336 #line 26 "parsegen.pcc"
337 #ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION
338 template class a_List<PrecRule>;
339 template a_List<PrecRule> * list_1_(ProductionSymbol x_1, a_List<ProductionSymbol> * x_2);
340 template a_List<PrecRule> * list_1_(ProductionSymbol x_list_1_);
341 template int boxed(const a_List<PrecRule> *);
342 template int untag(const a_List<PrecRule> *);
343 #endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */
345 ///////////////////////////////////////////////////////////////////////////////
347 // Instantiation of datatype List<a_List<ProductionSymbol> * >
349 ///////////////////////////////////////////////////////////////////////////////
350 #line 26 "parsegen.pcc"
351 #ifdef PROP_EXPLICIT_TEMPLATE_INSTANTIATION
352 template class a_List<a_List<ProductionSymbol> * >;
353 template a_List<a_List<ProductionSymbol> * > * list_1_(PrecRule x_1, a_List<PrecRule> * x_2);
354 template a_List<a_List<ProductionSymbol> * > * list_1_(PrecRule x_list_1_);
355 template int boxed(const a_List<a_List<ProductionSymbol> * > *);
356 template int untag(const a_List<a_List<ProductionSymbol> * > *);
357 #endif /* PROP_EXPLICIT_TEMPLATE_INSTANTIATION */
359 #line 30 "parsegen.pcc"
360 #line 30 "parsegen.pcc"
363 ///////////////////////////////////////////////////////////////////////////////
365 // Constructor and destructor
367 ///////////////////////////////////////////////////////////////////////////////
368 ParserCompiler:: ParserCompiler() {}
369 ParserCompiler::~ParserCompiler() {}
371 ///////////////////////////////////////////////////////////////////////////////
373 // Pretty printing methods for grammar
375 ///////////////////////////////////////////////////////////////////////////////
377 ///////////////////////////////////////////////////////////////////////////////
379 // Pretty print a production symbol
381 ///////////////////////////////////////////////////////////////////////////////
382 std::ostream& operator << (std::ostream& f, ProductionSymbol sym)
384 #line 52 "parsegen.pcc"
385 #line 65 "parsegen.pcc"
387 switch (sym->tag__) {
388 case a_ProductionSymbol::tag_TERMsym: {
389 #line 53 "parsegen.pcc"
390 f << '\'' << print_char(((ProductionSymbol_TERMsym *)sym)->TERMsym) << '\'';
391 #line 53 "parsegen.pcc"
392 } break;
393 case a_ProductionSymbol::tag_TERMSTRINGsym: {
394 #line 59 "parsegen.pcc"
395 f << ((ProductionSymbol_TERMSTRINGsym *)sym)->TERMSTRINGsym;
396 #line 59 "parsegen.pcc"
397 } break;
398 case a_ProductionSymbol::tag_TERMREGEXPsym: {
399 #line 60 "parsegen.pcc"
400 f << ((ProductionSymbol_TERMREGEXPsym *)sym)->TERMREGEXPsym;
401 #line 60 "parsegen.pcc"
402 } break;
403 case a_ProductionSymbol::tag_TOKENsym: {
404 if (((ProductionSymbol_TOKENsym *)sym)->TOKENsym) {
405 #line 55 "parsegen.pcc"
406 f << ((ProductionSymbol_TOKENsym *)sym)->TOKENsym->name;
407 #line 55 "parsegen.pcc"
408 } else {
409 #line 54 "parsegen.pcc"
410 f << "<?>";
411 #line 54 "parsegen.pcc"
413 } break;
414 case a_ProductionSymbol::tag_NONTERMsym: {
415 #line 56 "parsegen.pcc"
416 f << ((ProductionSymbol_NONTERMsym *)sym)->NONTERMsym;
417 #line 56 "parsegen.pcc"
418 } break;
419 case a_ProductionSymbol::tag_POSNONTERMsym: {
420 #line 57 "parsegen.pcc"
421 f << ((ProductionSymbol_POSNONTERMsym *)sym)->POSNONTERMsym;
422 #line 57 "parsegen.pcc"
423 } break;
424 case a_ProductionSymbol::tag_ACTIONsym: {
425 #line 58 "parsegen.pcc"
426 f << "{ ... }";
427 #line 58 "parsegen.pcc"
428 } break;
429 case a_ProductionSymbol::tag_PREDICATEsym: {
430 #line 61 "parsegen.pcc"
431 f << '(' << ((ProductionSymbol_PREDICATEsym *)sym)->PREDICATEsym << ')';
432 #line 61 "parsegen.pcc"
433 } break;
434 case a_ProductionSymbol::tag_PRECsym: {
435 if (((ProductionSymbol_PRECsym *)sym)->PRECsym) {
436 #line 62 "parsegen.pcc"
437 f << "prec: " << ((ProductionSymbol_PRECsym *)sym)->PRECsym->name;
438 #line 62 "parsegen.pcc"
439 } else {
440 #line 63 "parsegen.pcc"
441 f << "prec: ???";
442 #line 63 "parsegen.pcc"
444 } break;
445 case a_ProductionSymbol::tag_ERRORsym: {
446 #line 64 "parsegen.pcc"
447 f << '?';
448 #line 64 "parsegen.pcc"
449 } break;
450 default: {
451 #line 65 "parsegen.pcc"
452 f << "???";
453 #line 65 "parsegen.pcc"
454 } break;
457 #line 66 "parsegen.pcc"
458 #line 66 "parsegen.pcc"
460 return f;
463 ///////////////////////////////////////////////////////////////////////////////
465 // Pretty print a list of production symbols
467 ///////////////////////////////////////////////////////////////////////////////
468 std::ostream& operator << (std::ostream& f, ProductionSymbols P)
469 { for (ProductionSymbols l = P; l; l = l->_2)
470 { f << l->_1; if (l->_2) f << " "; }
471 return f;
474 ///////////////////////////////////////////////////////////////////////////////
476 // Pretty print a BNF
478 ///////////////////////////////////////////////////////////////////////////////
479 std::ostream& operator << (std::ostream& f, BNF bnf)
481 #line 87 "parsegen.pcc"
482 #line 94 "parsegen.pcc"
484 #line 89 "parsegen.pcc"
485 f << bnf->_1;
486 if (bnf->_2 != NOty) f << ' ' << bnf->_2 << ' ';
487 f << ':';
488 for_each (ProductionSymbols, p, bnf->_3)
489 { f << '\t' << p << '\n'; }
491 #line 94 "parsegen.pcc"
493 #line 95 "parsegen.pcc"
494 #line 95 "parsegen.pcc"
496 return f;
499 ///////////////////////////////////////////////////////////////////////////////
501 // Pretty print a list of alternatives
503 ///////////////////////////////////////////////////////////////////////////////
504 std::ostream& operator << (std::ostream& f, BNFs rules)
505 { for_each(BNF, rule, rules) f << rule;
506 return f;
509 ///////////////////////////////////////////////////////////////////////////////
511 // Print a precedence rule
513 ///////////////////////////////////////////////////////////////////////////////
514 std::ostream& operator << (std::ostream& f, PrecRule r)
516 #line 115 "parsegen.pcc"
517 #line 123 "parsegen.pcc"
519 #line 117 "parsegen.pcc"
521 #line 117 "parsegen.pcc"
522 #line 120 "parsegen.pcc"
524 PrecMode _V1 = r->_1;
525 switch (_V1) {
526 case LEFTassoc: {
527 #line 118 "parsegen.pcc"
528 f << "left: ";
529 #line 118 "parsegen.pcc"
530 } break;
531 case RIGHTassoc: {
532 #line 119 "parsegen.pcc"
533 f << "right: ";
534 #line 119 "parsegen.pcc"
535 } break;
536 default: {
537 #line 120 "parsegen.pcc"
538 f << "nonfix: ";
539 #line 120 "parsegen.pcc"
540 } break;
543 #line 121 "parsegen.pcc"
544 #line 121 "parsegen.pcc"
546 f << r->_2 << ' ' << r->_3 << '\n';
548 #line 123 "parsegen.pcc"
550 #line 124 "parsegen.pcc"
551 #line 124 "parsegen.pcc"
553 return f;
556 ///////////////////////////////////////////////////////////////////////////////
558 // Print a list of precedence rules
560 ///////////////////////////////////////////////////////////////////////////////
561 std::ostream& operator << (std::ostream& f,
562 #line 133 "parsegen.pcc"
563 a_List<PrecRule> *
564 #line 133 "parsegen.pcc"
565 rules)
566 { for_each (PrecRule, r, rules) f << r;
567 return f;
570 ///////////////////////////////////////////////////////////////////////////////
572 // Pretty print a grammar expression
574 ///////////////////////////////////////////////////////////////////////////////
575 std::ostream& operator << (std::ostream& f, GramExp exp)
577 #line 147 "parsegen.pcc"
579 switch (exp->tag__) {
580 case a_GramExp::tag_EXPgram: {
581 #line 145 "parsegen.pcc"
582 f << ((GramExp_EXPgram *)exp)->_1 << ((GramExp_EXPgram *)exp)->_3;
583 #line 145 "parsegen.pcc"
584 } break;
585 default: {} break;
588 #line 147 "parsegen.pcc"
589 #line 147 "parsegen.pcc"
591 return f;
594 ///////////////////////////////////////////////////////////////////////////////
596 // Method to create a syntax class
598 ///////////////////////////////////////////////////////////////////////////////
599 SyntaxClass::SyntaxClass
600 (CLASS_TYPE ct, Id id, Inherits i, TyQual q, Decls body)
601 : ClassDefinition(ct,id,
602 #line 158 "parsegen.pcc"
603 #line 158 "parsegen.pcc"
604 nil_1_
605 #line 158 "parsegen.pcc"
606 #line 158 "parsegen.pcc"
607 ,add_inherit("LR1Parser",
608 #line 158 "parsegen.pcc"
609 #line 158 "parsegen.pcc"
610 nil_1_
611 #line 158 "parsegen.pcc"
612 #line 158 "parsegen.pcc"
613 ,i),q,body),
614 production_rules(
615 #line 159 "parsegen.pcc"
616 #line 159 "parsegen.pcc"
617 nil_1_
618 #line 159 "parsegen.pcc"
619 #line 159 "parsegen.pcc"
621 precedence_rules(
622 #line 160 "parsegen.pcc"
623 #line 160 "parsegen.pcc"
624 nil_1_
625 #line 160 "parsegen.pcc"
626 #line 160 "parsegen.pcc"
628 G(0), parserGen(0), prec(0),
629 nonterm_map(string_hash, string_equal),
630 action_map(integer_hash, integer_equal),
631 inner_action_map(integer_hash, integer_equal),
632 line_map (integer_hash, integer_equal),
633 predicate_map(integer_hash, integer_equal)
636 SyntaxClass::~SyntaxClass() {}
638 ///////////////////////////////////////////////////////////////////////////////
640 // Method to generate the interface of a parser class
642 ///////////////////////////////////////////////////////////////////////////////
643 void SyntaxClass::gen_class_interface (CodeGen& C)
645 C.pr("%-%^public:%+"
646 "%^%/"
647 "%^// Parser table type definitions"
648 "%^%/"
649 "%^typedef LR1Parser Super;"
650 "%^typedef Super::Offset Offset;"
651 "%^typedef Super::State State;"
652 "%^typedef Super::Rule Rule;"
653 "%^typedef Super::Symbol Symbol;"
654 "%^typedef Super::ProductionLength ProductionLength;"
655 "%^typedef Super::ShortSymbol ShortSymbol;"
656 "%^typedef Super::EquivMap EquivMap;"
657 "%^enum { INITIAL_STACK_SIZE_ = 256,"
658 "%^ MAX_STACK_SIZE_ = 8192"
659 "%^ };"
660 "%-%^protected:%+"
661 "%^%/"
662 "%^// Semantic value stack"
663 "%^%/"
664 "%^union %s_semantic_stack_type * t__, * bot__;"
665 "%^int stack_size__;"
666 "%^int heap_allocated__;"
667 "%-%^public:%+"
668 "%^%/"
669 "%^// Constructor and parsing method"
670 "%^%/"
671 "%^%s();"
672 "%^virtual void parse();"
673 "%^void action_driver(const Rule);"
674 "%-%^private:%+"
675 "%^void adjust_stack(int);\n"
676 "%^void grow_semantic_stack();",
677 class_name, class_name
681 ///////////////////////////////////////////////////////////////////////////////
683 // Method to generate a parser given a grammar expression.
685 ///////////////////////////////////////////////////////////////////////////////
686 void ParserCompiler::gen_parser(Id id, GramExp e)
687 { // if (debug) cerr << id << ":\n" << e;
689 SyntaxClass * C = (SyntaxClass*)
690 ClassDefinition::lookup_class(ClassDefinition::SYNTAX_CLASS, id);
691 if (C) C->gen_parser(*this,e);
694 ///////////////////////////////////////////////////////////////////////////////
696 // Method to generate a parser given a grammar expression.
698 ///////////////////////////////////////////////////////////////////////////////
699 void SyntaxClass::gen_parser(CodeGen& C, GramExp e)
701 initialize();
702 compile_grammar(C, e);
703 cleanup();
706 ///////////////////////////////////////////////////////////////////////////////
708 // Method to compile a grammar
710 ///////////////////////////////////////////////////////////////////////////////
711 void SyntaxClass::compile_grammar(CodeGen& C, GramExp e)
713 #line 245 "parsegen.pcc"
714 #line 250 "parsegen.pcc"
716 switch (e->tag__) {
717 case a_GramExp::tag_EXPgram: {
718 #line 247 "parsegen.pcc"
719 compile_rules(C, ((GramExp_EXPgram *)e)->_1, ((GramExp_EXPgram *)e)->_2, ((GramExp_EXPgram *)e)->_3);
721 #line 248 "parsegen.pcc"
722 } break;
723 default: {
724 #line 250 "parsegen.pcc"
725 bug("SyntaxClass::compile_grammar");
726 #line 250 "parsegen.pcc"
727 } break;
730 #line 251 "parsegen.pcc"
731 #line 251 "parsegen.pcc"
735 ///////////////////////////////////////////////////////////////////////////////
737 // Collect the names of the non-terminals
738 // and count the number of productions.
740 ///////////////////////////////////////////////////////////////////////////////
741 void SyntaxClass::preprocess_grammar ()
742 { number_of_productions = 0;
744 ////////////////////////////////////////////////////////////////////////////
745 // Compute the terminal and action encoding
746 ////////////////////////////////////////////////////////////////////////////
747 { for_each(BNF, r, production_rules)
749 #line 267 "parsegen.pcc"
750 #line 291 "parsegen.pcc"
752 #line 269 "parsegen.pcc"
753 for_each (ProductionSymbols, p, r->_3)
754 { Bool no_action = true;
755 for_each (ProductionSymbol, s, p)
756 { s->set_loc();
758 #line 273 "parsegen.pcc"
759 #line 285 "parsegen.pcc"
761 switch (s->tag__) {
762 case a_ProductionSymbol::tag_TOKENsym: {
763 if (((ProductionSymbol_TOKENsym *)s)->TOKENsym) {
764 if (((ProductionSymbol_TOKENsym *)s)->TOKENsym->alg_ty) {
765 switch (((ProductionSymbol_TOKENsym *)s)->TOKENsym->alg_ty->tag__) {
766 case a_Ty::tag_TYCONty: {
767 if (boxed(((Ty_TYCONty *)((ProductionSymbol_TOKENsym *)s)->TOKENsym->alg_ty)->_1)) {
768 switch (((Ty_TYCONty *)((ProductionSymbol_TOKENsym *)s)->TOKENsym->alg_ty)->_1->tag__) {
769 case a_TyCon::tag_DATATYPEtycon: {
770 #line 278 "parsegen.pcc"
771 if ((((TyCon_DATATYPEtycon *)((Ty_TYCONty *)((ProductionSymbol_TOKENsym *)s)->TOKENsym->alg_ty)->_1)->qualifiers & QUALlexeme) == 0)
772 error("%Lconstructor %s is not a lexeme\n",((ProductionSymbol_TOKENsym *)s)->TOKENsym->name);
773 if (tag_of(((ProductionSymbol_TOKENsym *)s)->TOKENsym) > max_term)
774 max_term = tag_of(((ProductionSymbol_TOKENsym *)s)->TOKENsym);
776 #line 282 "parsegen.pcc"
777 } break;
778 default: {
779 L1:; } break;
781 } else { goto L1; }
782 } break;
783 default: { goto L1; } break;
785 } else { goto L1; }
786 } else { goto L1; }
787 } break;
788 case a_ProductionSymbol::tag_ACTIONsym: {
789 #line 283 "parsegen.pcc"
790 no_action = false;
791 #line 283 "parsegen.pcc"
792 } break;
793 default: { goto L1; } break;
796 #line 285 "parsegen.pcc"
797 #line 285 "parsegen.pcc"
800 if (r->_2 != NOty && no_action)
801 msg("%!%wmissing synthesized value in production: %s %T:",
802 r->loc(), r->_1, r->_2) << p << '\n';
805 #line 291 "parsegen.pcc"
807 #line 292 "parsegen.pcc"
808 #line 292 "parsegen.pcc"
813 ////////////////////////////////////////////////////////////////////////////
814 // Set the error token
815 ////////////////////////////////////////////////////////////////////////////
816 error_term = ++max_term;
817 max_nonterm = max_term + 1;
819 ////////////////////////////////////////////////////////////////////////////
820 // Compute the non-terminals encoding.
821 ////////////////////////////////////////////////////////////////////////////
822 { for_each(BNF, r, production_rules)
824 #line 306 "parsegen.pcc"
825 #line 313 "parsegen.pcc"
827 #line 308 "parsegen.pcc"
828 if (! nonterm_map.contains(r->_1))
829 { max_nonterm++;
830 nonterm_map.insert(r->_1,(HashTable::Value)max_nonterm);
832 number_of_productions += length(r->_3);
834 #line 313 "parsegen.pcc"
836 #line 314 "parsegen.pcc"
837 #line 314 "parsegen.pcc"
843 ///////////////////////////////////////////////////////////////////////////////
845 // Translate rules into grammar form.
847 ///////////////////////////////////////////////////////////////////////////////
848 void SyntaxClass::translate_into_grammar ()
849 { int i = 0; // production number
850 min_action = Grammar::First_action;
851 for_each(BNF, r, production_rules)
853 #line 328 "parsegen.pcc"
854 #line 380 "parsegen.pcc"
856 #line 330 "parsegen.pcc"
857 Grammar::NonTerminal A = (Grammar::NonTerminal)nonterm_map[r->_1];
858 symbol_names[A] = r->_1;
859 for_each (ProductionSymbols, p, r->_3)
860 { int j = 1;
861 int non_terms_or_actions = 0;
862 ty_map[i] = r->_2;
863 Grammar::Production P =
864 (Grammar::Production)mem_pool.c_alloc
865 (sizeof(Grammar::Symbol) * (length(p) + 2));
866 P[0] = A;
867 for (
868 #line 340 "parsegen.pcc"
869 a_List<ProductionSymbol> *
870 #line 340 "parsegen.pcc"
871 L = p; L; L = L->_2)
872 { ProductionSymbol X = L->_1;
873 X->set_loc();
875 #line 373 "parsegen.pcc"
877 switch (X->tag__) {
878 case a_ProductionSymbol::tag_TERMsym: {
879 #line 345 "parsegen.pcc"
880 P[j] = ((ProductionSymbol_TERMsym *)X)->TERMsym;
881 if (symbol_names[((ProductionSymbol_TERMsym *)X)->TERMsym] == 0)
882 symbol_names[((ProductionSymbol_TERMsym *)X)->TERMsym] =
883 #line 347 "parsegen.pcc"
884 #line 347 "parsegen.pcc"
885 _p_a_r_s_e_g_e_nco_c_c_Q1
886 #line 347 "parsegen.pcc"
887 #line 347 "parsegen.pcc"
888 + print_char(((ProductionSymbol_TERMsym *)X)->TERMsym) +
889 #line 347 "parsegen.pcc"
890 #line 347 "parsegen.pcc"
891 _p_a_r_s_e_g_e_nco_c_c_Q1
892 #line 347 "parsegen.pcc"
893 #line 347 "parsegen.pcc"
896 #line 348 "parsegen.pcc"
897 } break;
898 case a_ProductionSymbol::tag_TOKENsym: {
899 if (((ProductionSymbol_TOKENsym *)X)->TOKENsym) {
900 #line 357 "parsegen.pcc"
901 P[j] = tag_of(((ProductionSymbol_TOKENsym *)X)->TOKENsym);
902 symbol_names[P[j]] = ((ProductionSymbol_TOKENsym *)X)->TOKENsym->name;
904 #line 359 "parsegen.pcc"
905 } else {
906 #line 360 "parsegen.pcc"
907 P[j] = ' ';
908 #line 360 "parsegen.pcc"
910 } break;
911 case a_ProductionSymbol::tag_NONTERMsym: {
912 #line 350 "parsegen.pcc"
913 if (! nonterm_map.contains(((ProductionSymbol_NONTERMsym *)X)->NONTERMsym))
914 { error("%Lundefined non-terminal %s\n",((ProductionSymbol_NONTERMsym *)X)->NONTERMsym); }
915 else
916 { P[j] = (Grammar::NonTerminal)nonterm_map[((ProductionSymbol_NONTERMsym *)X)->NONTERMsym]; }
917 ++non_terms_or_actions;
919 #line 355 "parsegen.pcc"
920 } break;
921 case a_ProductionSymbol::tag_ACTIONsym: {
922 #line 362 "parsegen.pcc"
923 P[j] = min_action;
924 action_map.insert(HashTable::Key(min_action), ((ProductionSymbol_ACTIONsym *)X)->ACTIONsym);
925 line_map.insert(HashTable::Key(min_action),
926 HashTable::Value(X->begin_line));
927 if (L->_2 !=
928 #line 366 "parsegen.pcc"
929 #line 366 "parsegen.pcc"
930 nil_1_
931 #line 366 "parsegen.pcc"
932 #line 366 "parsegen.pcc"
934 inner_action_map.insert(HashTable::Key(min_action),
935 HashTable::Value(non_terms_or_actions));
936 min_action--;
937 ++non_terms_or_actions;
939 #line 371 "parsegen.pcc"
940 } break;
941 case a_ProductionSymbol::tag_ERRORsym: {
942 #line 372 "parsegen.pcc"
943 P[j] = error_term;
944 #line 372 "parsegen.pcc"
945 } break;
946 default: {
947 #line 373 "parsegen.pcc"
948 bug("translate_into_grammar()");
949 #line 373 "parsegen.pcc"
950 } break;
953 #line 374 "parsegen.pcc"
954 #line 374 "parsegen.pcc"
956 j++;
958 P[j] = Grammar::END_PRODUCTION;
959 productions[i++] = P;
962 #line 380 "parsegen.pcc"
964 #line 381 "parsegen.pcc"
965 #line 381 "parsegen.pcc"
970 ///////////////////////////////////////////////////////////////////////////////
972 // Method to enter the precedence information
974 ///////////////////////////////////////////////////////////////////////////////
975 void SyntaxClass::define_operator_precedence ()
976 { for_each (PrecRule, r, precedence_rules)
978 #line 392 "parsegen.pcc"
979 #line 417 "parsegen.pcc"
981 #line 394 "parsegen.pcc"
982 OpPrecedence::Associativity a;
984 #line 395 "parsegen.pcc"
985 #line 398 "parsegen.pcc"
987 PrecMode _V2 = r->_1;
988 switch (_V2) {
989 case LEFTassoc: {
990 #line 396 "parsegen.pcc"
991 a = OpPrecedence::Left;
992 #line 396 "parsegen.pcc"
993 } break;
994 case RIGHTassoc: {
995 #line 397 "parsegen.pcc"
996 a = OpPrecedence::Right;
997 #line 397 "parsegen.pcc"
998 } break;
999 default: {
1000 #line 398 "parsegen.pcc"
1001 a = OpPrecedence::None;
1002 #line 398 "parsegen.pcc"
1003 } break;
1006 #line 399 "parsegen.pcc"
1007 #line 399 "parsegen.pcc"
1009 for_each(ProductionSymbol, s, r->_3)
1011 #line 401 "parsegen.pcc"
1012 #line 414 "parsegen.pcc"
1014 switch (s->tag__) {
1015 case a_ProductionSymbol::tag_TERMsym: {
1016 #line 403 "parsegen.pcc"
1017 prec->precedence(G->map(((ProductionSymbol_TERMsym *)s)->TERMsym),r->_2);
1018 prec->associativity(G->map(((ProductionSymbol_TERMsym *)s)->TERMsym),a);
1020 #line 405 "parsegen.pcc"
1021 } break;
1022 case a_ProductionSymbol::tag_TOKENsym: {
1023 #line 407 "parsegen.pcc"
1024 prec->precedence(G->map(tag_of(((ProductionSymbol_TOKENsym *)s)->TOKENsym)),r->_2);
1025 prec->associativity(G->map(tag_of(((ProductionSymbol_TOKENsym *)s)->TOKENsym)),a);
1027 #line 409 "parsegen.pcc"
1028 } break;
1029 default: {
1030 #line 411 "parsegen.pcc"
1031 s->set_loc();
1032 error("%Lprecedence symbol must be a terminal: ")
1033 << s << '\n';
1035 #line 414 "parsegen.pcc"
1036 } break;
1039 #line 415 "parsegen.pcc"
1040 #line 415 "parsegen.pcc"
1044 #line 417 "parsegen.pcc"
1046 #line 418 "parsegen.pcc"
1047 #line 418 "parsegen.pcc"
1052 ///////////////////////////////////////////////////////////////////////////////
1054 // Add a new reference of a non-terminal
1056 ///////////////////////////////////////////////////////////////////////////////
1057 static void add_use (HashTable& table, Id nonterm, int item_number)
1058 { HashTable::Entry * e = table.lookup(nonterm);
1059 if (e)
1061 #line 430 "parsegen.pcc"
1062 a_List<int> *
1063 #line 430 "parsegen.pcc"
1064 old_uses = (a_List<int> *
1065 #line 430 "parsegen.pcc"
1066 ) table.value(e);
1067 table.insert(nonterm,
1068 #line 431 "parsegen.pcc"
1069 list_1_(item_number,old_uses)
1070 #line 431 "parsegen.pcc"
1071 #line 431 "parsegen.pcc"
1073 } else
1074 { table.insert(nonterm,
1075 #line 433 "parsegen.pcc"
1076 #line 433 "parsegen.pcc"
1077 list_1_(item_number)
1078 #line 433 "parsegen.pcc"
1079 #line 433 "parsegen.pcc"
1084 ///////////////////////////////////////////////////////////////////////////////
1086 // Generate the semantic stack definition
1088 ///////////////////////////////////////////////////////////////////////////////
1089 void SyntaxClass::generate_semantic_stack_definition (CodeGen& C)
1091 ////////////////////////////////////////////////////////////////////////////
1092 // Mapping from nonterminal to type
1093 ////////////////////////////////////////////////////////////////////////////
1094 HashTable nonterm_to_ty(string_hash,string_equal);
1095 HashTable nonterm_to_uses(string_hash,string_equal);
1097 ////////////////////////////////////////////////////////////////////////////
1098 // Generate the semantic stack definition.
1099 ////////////////////////////////////////////////////////////////////////////
1100 C.pr ("%^%/"
1101 "%^// Semantic value stack for syntax class %s"
1102 "%^%/"
1103 "%^union %s_semantic_stack_type {%+"
1104 "%^int dummy;",
1105 class_name, class_name);
1107 ////////////////////////////////////////////////////////////////////////////
1109 // First, we'll make sure that all productions with the same non-terminal
1110 // have the same synthesized attribute type.
1112 ////////////////////////////////////////////////////////////////////////////
1113 for_each (BNF, rl, production_rules)
1115 #line 467 "parsegen.pcc"
1116 #line 478 "parsegen.pcc"
1118 #line 469 "parsegen.pcc"
1119 HashTable::Entry * e = nonterm_to_ty.lookup(rl->_1);
1120 if (e)
1121 { Ty last_ty = (Ty)nonterm_to_ty.value(e);
1122 if (! ty_equal(rl->_2,last_ty))
1123 { rl->set_loc();
1124 error("%Lexpecting type '%T' but found '%T'\n", last_ty, rl->_2);
1127 nonterm_to_ty.insert(rl->_1,rl->_2);
1129 #line 478 "parsegen.pcc"
1131 #line 479 "parsegen.pcc"
1132 #line 479 "parsegen.pcc"
1136 ////////////////////////////////////////////////////////////////////////////
1138 // Now, we found out all references of all non-terminals.
1140 ////////////////////////////////////////////////////////////////////////////
1141 int item_number = 0;
1143 for_each (BNF, r, production_rules)
1145 #line 490 "parsegen.pcc"
1146 #line 511 "parsegen.pcc"
1148 #line 492 "parsegen.pcc"
1149 for_each (ProductionSymbols, p, r->_3)
1150 { ++item_number;
1151 if (r->_2 != NOty)
1152 add_use(nonterm_to_uses,r->_1,item_number);
1153 for_each (ProductionSymbol, X, p)
1154 { ++item_number;
1156 #line 498 "parsegen.pcc"
1157 #line 508 "parsegen.pcc"
1159 switch (X->tag__) {
1160 case a_ProductionSymbol::tag_NONTERMsym: {
1161 #line 500 "parsegen.pcc"
1162 HashTable::Entry * e = nonterm_to_ty.lookup(((ProductionSymbol_NONTERMsym *)X)->NONTERMsym);
1163 if (e)
1164 { Ty this_ty = (Ty)nonterm_to_ty.value(e);
1165 if (this_ty != NOty)
1166 add_use(nonterm_to_uses,((ProductionSymbol_NONTERMsym *)X)->NONTERMsym,item_number);
1169 #line 506 "parsegen.pcc"
1170 } break;
1171 default: {} break;
1174 #line 508 "parsegen.pcc"
1175 #line 508 "parsegen.pcc"
1180 #line 511 "parsegen.pcc"
1182 #line 512 "parsegen.pcc"
1183 #line 512 "parsegen.pcc"
1187 ////////////////////////////////////////////////////////////////////////////
1189 // Then we print out the type definitions for all the synthesized
1190 // attributes.
1192 ////////////////////////////////////////////////////////////////////////////
1193 { int i = 0;
1194 for_each (BNF, r, production_rules)
1196 #line 523 "parsegen.pcc"
1197 #line 538 "parsegen.pcc"
1199 #line 525 "parsegen.pcc"
1200 if (r->_2 != NOty)
1202 #line 526 "parsegen.pcc"
1203 a_List<int> *
1204 #line 526 "parsegen.pcc"
1205 uses = (a_List<int> *
1206 #line 526 "parsegen.pcc"
1207 )nonterm_to_uses[r->_1];
1208 if (uses !=
1209 #line 527 "parsegen.pcc"
1210 nil_1_
1211 #line 527 "parsegen.pcc"
1212 #line 527 "parsegen.pcc"
1214 { C.pr ("%#"
1215 "%^typedef %tATTRIBUTE_%i;"
1216 "%^ATTRIBUTE_%i ",
1217 r->begin_line, r->file_name, r->_2, "", i, i);
1218 for (
1219 #line 532 "parsegen.pcc"
1220 a_List<int> *
1221 #line 532 "parsegen.pcc"
1222 l = uses; l; l = l->_2)
1223 { C.pr ("_%i", l->_1); if (l->_2) C.pr(", "); }
1224 C.pr (";\n");
1225 i++;
1230 #line 539 "parsegen.pcc"
1231 #line 539 "parsegen.pcc"
1235 C.pr ("%-%^};\n\n");
1238 ///////////////////////////////////////////////////////////////////////////////
1240 // Generate debugging tables
1242 ///////////////////////////////////////////////////////////////////////////////
1243 void SyntaxClass::generate_debugging_tables (CodeGen& C)
1244 { C.pr ("%^%/"
1245 "%^// Debugging tables for syntax class %s"
1246 "%^%/"
1247 "\n#ifdef DEBUG_%s",
1248 class_name, class_name);
1250 ////////////////////////////////////////////////////////////////////////////
1251 // Generate the mapping from rule number to source code line number.
1252 ////////////////////////////////////////////////////////////////////////////
1253 C.pr ("%^static const int %s_line[] =%^{%+%^", class_name);
1254 { int * line_table = (int *)mem_pool.c_alloc(G->size() * sizeof(int));
1255 for (Grammar::Action a = Grammar::First_action; a > min_action; a--)
1256 { int r = G->rule_of(a);
1257 if (r >= 0)
1258 { line_table[r] = (int)line_map[HashTable::Key(a)]; }
1260 for (int r = 0; r < G->size(); r++)
1261 { C.pr ("%i", line_table[r]);
1262 if (r < G->size() - 1) C.pr(", ");
1263 if (r % 8 == 7) C.pr ("%^");
1266 C.pr ("%-%^};\n\n");
1268 ////////////////////////////////////////////////////////////////////////////
1269 // Generate the mapping from equivalence class number to name.
1270 ////////////////////////////////////////////////////////////////////////////
1271 C.pr ("%^static const char * const %s_symbolname[] =%^{%+%^", class_name);
1272 { Id * sym_map = (Id *)
1273 mem_pool.c_alloc((G->max_non_terminal() + 1) * sizeof(Id));
1274 for (int c = 0; c <= max_nonterm; c++)
1275 if (symbol_names[c]) sym_map[G->map(c)] = symbol_names[c];
1276 for (int i = 0; i <= G->max_non_terminal(); i++)
1277 { C.pr ("%s", sym_map[i] ? make_quoted_string(sym_map[i]) : "\"???\"");
1278 if (i < G->max_non_terminal()) C.pr (", ");
1279 if (i % 8 == 7) C.pr ("%^");
1282 C.pr ("%-%^};\n\n");
1284 ////////////////////////////////////////////////////////////////////////////
1285 // Generate the mapping from rule number to production.
1286 ////////////////////////////////////////////////////////////////////////////
1287 { for (int r = 0; r < G->size(); r++)
1288 { C.pr("%^static const DFATables::ShortSymbol %s_rhs_%i[] = { ",
1289 class_name, r);
1290 int len = G->length(G->rhs(r));
1291 for (int i = 0; i < len; i++)
1292 { C.pr ("%i, ", (int)G->rhs(r)[i]); }
1293 C.pr(" -1 };");
1296 { C.pr ("%^static const DFATables::ShortSymbol * %s_rhs[] =%^{%+",
1297 class_name);
1298 for (int r = 0; r < G->size(); r++)
1299 { C.pr ("%^%s_rhs_%i", class_name, r);
1300 if (r < G->size() - 1) C.pr(", ");
1302 C.pr ("%-%^};\n\n");
1304 C.pr ("\n#endif\n\n");
1307 ///////////////////////////////////////////////////////////////////////////////
1309 // Generate the parser tables
1311 ///////////////////////////////////////////////////////////////////////////////
1312 void SyntaxClass::generate_parser_tables (CodeGen& C)
1314 ////////////////////////////////////////////////////////////////////////////
1315 // Generate the parser tables.
1316 ////////////////////////////////////////////////////////////////////////////
1317 C.pr ( "%^%/"
1318 "%^// Encoded parser tables for syntax class %s"
1319 "%^%/",
1320 class_name);
1321 parserGen->gen_code(C.pr(""),class_name);
1324 void SyntaxClass::generate_action_driver(CodeGen& C)
1326 ////////////////////////////////////////////////////////////////////////////
1328 // Generate the parser driver header.
1330 ////////////////////////////////////////////////////////////////////////////
1331 C.pr ( "\n"
1332 "%^%/"
1333 "%^// Parser driver for syntax class %s"
1334 "%^%/"
1335 "%^inline void %s::action_driver(const Rule _r_)"
1336 "%^{\n%+"
1337 "%^%s_semantic_stack_type syn_;",
1338 class_name, class_name, class_name
1341 ////////////////////////////////////////////////////////////////////////////
1342 // Generate the debugging function
1343 ////////////////////////////////////////////////////////////////////////////
1344 C.pr ("\n%^%/"
1345 "%^// Tracing code for syntax class %s"
1346 "%^%/"
1347 "#ifdef DEBUG_%s"
1348 "%^{ cerr << \"Reducing via rule \" << _r_ << \" at line \""
1349 "%^ << %s_line[_r_] << \", \""
1350 "%^ << %s_symbolname[%s_lhs[_r_]] << \" <- \";"
1351 "%^ for (const DFATables::ShortSymbol * _p_ = %s_rhs[_r_]; *_p_ >= 0; _p_++)"
1352 "%^ cerr << %s_symbolname[*_p_] << ' ';"
1353 "%^ cerr << '\\n';"
1354 "%^}"
1355 "\n#endif\n\n",
1356 class_name, class_name, class_name, class_name,
1357 class_name, class_name, class_name, class_name, class_name
1360 generate_semantic_actions(C);
1362 C.pr("%-%^}\n\n");
1365 ///////////////////////////////////////////////////////////////////////////////
1367 // Generate the parse method
1369 ///////////////////////////////////////////////////////////////////////////////
1370 void SyntaxClass::generate_parse_method(CodeGen& C)
1372 C.pr ("%^%/"
1373 "%^// Parsing method for parser class %s"
1374 "%^%/"
1375 "%^void %s::parse()"
1376 "%^{"
1377 "%^ %s_semantic_stack_type stack__[INITIAL_STACK_SIZE_];"
1378 "%^ t__ = bot__ = stack__;"
1379 "%^ stack_size__ = sizeof(stack__)/sizeof(stack__[0]) - 1;"
1380 "%^ heap_allocated__ = 0;"
1381 "%^ parser_prefix();"
1382 "%^ LR1ParserDriver<%s,(LR1Parser::State)%i> drv;"
1383 "%^ drv.driver(*this);"
1384 "%^ parser_suffix();"
1385 "%^ if (bot__ != stack__) delete [] bot__;"
1386 "%^}\n\n",
1387 class_name, class_name, class_name,
1388 class_name, (int)parserGen->final_state()
1392 ///////////////////////////////////////////////////////////////////////////////
1394 // Method to generate the semantic actions
1396 ///////////////////////////////////////////////////////////////////////////////
1397 void SyntaxClass::generate_semantic_actions(CodeGen& C)
1399 ////////////////////////////////////////////////////////////////////////////
1400 // Generate the switch on the reduction rules.
1401 ////////////////////////////////////////////////////////////////////////////
1402 C.pr ( "%^%/"
1403 "%^// Actions for syntax class %s"
1404 "%^%/"
1405 "%^t__ -= %s_ncount[_r_];"
1406 "%^switch (_r_) {\n%+",
1407 class_name, class_name, class_name, class_name
1410 ////////////////////////////////////////////////////////////////////////////
1411 // Generate the parsing actions
1412 ////////////////////////////////////////////////////////////////////////////
1413 C.pr("\n"
1414 "#undef to__\n"
1415 "#define to__ 0\n"
1417 for (Grammar::Action a = Grammar::First_action; a > min_action; a--)
1418 { HashTable::Entry * e = inner_action_map.lookup(HashTable::Key(a));
1419 if (e)
1420 { C.pr("\n"
1421 "#undef to__\n"
1422 "#define to__ -%i",
1423 (int)(e->v)
1426 C.pr ("%^case %i: {%+%&%-} break;",
1427 (int)G->rule_of(a), action_map[HashTable::Key(a)]);
1428 if (e)
1429 { C.pr("\n"
1430 "#undef to__\n"
1431 "#define to__ 0\n"
1435 C.pr ("%-%^}"
1436 "%^if (t__ >= bot__ + stack_size__) grow_semantic_stack();"
1437 "%^*++t__ = syn_;"
1441 ///////////////////////////////////////////////////////////////////////////////
1443 // Method to initialize the data structures
1445 ///////////////////////////////////////////////////////////////////////////////
1446 void SyntaxClass::initialize()
1448 number_of_productions = 0;
1449 min_term = 0;
1450 max_term = 255;
1451 error_term = 255;
1452 max_nonterm = 255;
1453 start_symbol = 0;
1454 min_action = Grammar::First_action;
1455 symbol_names = 0;
1456 productions = 0;
1457 ty_map = 0;
1458 G = 0;
1459 parserGen = 0;
1460 prec = 0;
1463 ///////////////////////////////////////////////////////////////////////////////
1465 // Method to cleanup all the data structures
1467 ///////////////////////////////////////////////////////////////////////////////
1468 void SyntaxClass::cleanup()
1470 nonterm_map.clear();
1471 action_map.clear();
1472 inner_action_map.clear();
1473 line_map.clear();
1474 predicate_map.clear();
1475 productions = 0;
1476 symbol_names = 0;
1477 ty_map = 0;
1478 delete G;
1479 delete parserGen;
1480 delete prec;
1483 ///////////////////////////////////////////////////////////////////////////////
1485 // Method to compile a set of production rules
1487 ///////////////////////////////////////////////////////////////////////////////
1488 void SyntaxClass::compile_rules
1489 ( CodeGen& C,
1490 PrecRules prec_rules,
1491 ShiftReduceErrors expected_errors,
1492 BNFs p_rules
1494 { int last_errors = errors;
1496 ////////////////////////////////////////////////////////////////////////////
1498 // Initialize all the data structures used
1500 ////////////////////////////////////////////////////////////////////////////
1501 production_rules = p_rules;
1502 precedence_rules = prec_rules;
1504 ////////////////////////////////////////////////////////////////////////////
1506 // Collect the names of the non-terminals in this grammar
1508 ////////////////////////////////////////////////////////////////////////////
1509 preprocess_grammar();
1511 ////////////////////////////////////////////////////////////////////////////
1513 // Translate into grammar form.
1515 ////////////////////////////////////////////////////////////////////////////
1516 productions = (Grammar::Production *)mem_pool.c_alloc
1517 (sizeof(Grammar::Production) * number_of_productions);
1518 symbol_names = (Id *)mem_pool.c_alloc(sizeof(Id) * (max_nonterm + 1));
1519 ty_map = (Ty *)mem_pool.c_alloc(sizeof(Ty) * number_of_productions);
1520 translate_into_grammar();
1521 symbol_names[error_term] = "?";
1522 if (last_errors < errors) return;
1523 if (number_of_productions > 0)
1524 start_symbol = productions[0][0];
1526 ////////////////////////////////////////////////////////////////////////////
1527 // Create the grammar and put it into canonical form
1528 ////////////////////////////////////////////////////////////////////////////
1529 Grammar G0(productions, number_of_productions, min_term, max_term,
1530 start_symbol, symbol_names);
1531 G = new Grammar(G0.makeCanonical());
1533 ////////////////////////////////////////////////////////////////////////////
1534 // Compile the grammar into tables.
1535 ////////////////////////////////////////////////////////////////////////////
1536 parserGen = new LALR1Gen;
1537 prec = new OpPrecedence (*G);
1538 define_operator_precedence();
1539 parserGen->compile(*G,*prec);
1541 ////////////////////////////////////////////////////////////////////////////
1543 // Process errors
1545 ////////////////////////////////////////////////////////////////////////////
1546 process_parser_errors(expected_errors);
1548 ////////////////////////////////////////////////////////////////////////////
1550 // Generate a report
1552 ////////////////////////////////////////////////////////////////////////////
1553 if (options.generate_report)
1554 { std::ostream& log = open_logfile();
1555 log << "[Syntax class " << class_name << "]\n";
1556 parserGen->print_report(log, options.verbosity) << '\n';
1559 gen_class_implementation(C,
1560 #line 866 "parsegen.pcc"
1561 #line 866 "parsegen.pcc"
1562 nil_1_
1563 #line 866 "parsegen.pcc"
1564 #line 866 "parsegen.pcc"
1565 ,EXTERNAL_INSTANTIATION);
1568 ////////////////////////////////////////////////////////////////////////////
1570 // Method to generate the implementation of the parser class.
1572 ////////////////////////////////////////////////////////////////////////////
1573 void SyntaxClass::gen_class_implementation(CodeGen& C, Tys tys, DefKind k)
1575 generate_parser_tables(C); // encoded tables
1576 generate_debugging_tables(C); // auxiliary tables for debugging
1577 generate_semantic_stack_definition(C); // semantic stack definition
1578 generate_action_driver(C); // the action driver
1579 generate_parse_method(C); // the main parse method
1580 generate_semantic_stack_adjustment(C); // how to adjust the stack
1581 generate_semantic_stack_growth(C); // how to grow the stack
1582 gen_class_constructor(C,tys,k); // constructor of this class
1585 ////////////////////////////////////////////////////////////////////////////
1587 // Method to process parser errors
1589 ////////////////////////////////////////////////////////////////////////////
1590 void SyntaxClass::process_parser_errors(ShiftReduceErrors expected_errors)
1592 int sr_conflicts = parserGen->shift_reduce_conflicts();
1593 int rr_conflicts = parserGen->reduce_reduce_conflicts();
1595 if (sr_conflicts > 0 && expected_errors < 0)
1596 { msg(expected_errors == -1 ? "%Lwarning: %i%s%s\n" : "%L%w%i%s%s\n",
1597 sr_conflicts, " shift/reduce conflicts in syntax class ",
1598 class_name);
1601 if (expected_errors >= 0 && sr_conflicts != expected_errors)
1602 { msg("%L%wexpecting %i shift/reduce conflicts but found %i"
1603 " in syntax class %s\n",
1604 expected_errors, sr_conflicts, class_name);
1607 if (rr_conflicts > 0)
1608 { msg("%L%w%i reduce/reduce conflicts in syntax class %s\n",
1609 rr_conflicts, class_name);
1613 //////////////////////////////////////////////////////////////////////////////
1615 // Generate the semantic stack growing method
1617 //////////////////////////////////////////////////////////////////////////////
1618 void SyntaxClass::generate_semantic_stack_growth(CodeGen& C)
1620 C.pr(
1621 "%^void %s::grow_semantic_stack()\n"
1622 "%^{%+"
1623 "%^int N = (stack_size__ + 1) * 2;"
1624 "%^%s_semantic_stack_type * S = new %s_semantic_stack_type [N];"
1625 "%^if (N >= LR1Parser::SEMANTIC_STACK_SIZE) "
1626 "%^ error_report(\"Warning: semantic stack overflow\");"
1627 "%^memcpy(S, bot__, sizeof(%s_semantic_stack_type) * (stack_size__ + 1));"
1628 "%^if (heap_allocated__) delete [] bot__;"
1629 "%^t__ = S + (t__ - bot__);"
1630 "%^bot__ = S;"
1631 "%^stack_size__ = N - 1;"
1632 "%^heap_allocated__ = 1;"
1633 "%-%^}\n\n",
1634 class_name, class_name, class_name, class_name );
1637 //////////////////////////////////////////////////////////////////////////////
1639 // Method to generate the stack adjustment method
1641 //////////////////////////////////////////////////////////////////////////////
1642 void SyntaxClass::generate_semantic_stack_adjustment(CodeGen& C)
1644 C.pr("%^void %s::adjust_stack(int offset) { t__ += offset; }\n\n",
1645 class_name);
1648 //////////////////////////////////////////////////////////////////////////////
1650 // Method to generate the class constructor that initializes all
1651 // the parser tables.
1653 //////////////////////////////////////////////////////////////////////////////
1654 void SyntaxClass::gen_class_constructor_initializers(CodeGen& C,Tys,DefKind)
1656 Id id = class_name;
1657 C.pr("%^ : Super(%s_base,%s_check,%s_def,%s_defact,%s_next,"
1658 "%^ %s_len,%s_ncount,%s_lhs,%s_equiv,%i,%i,%i)",
1659 id, id, id, id, id, id, id, id, id,
1660 (int)error_term, (int)max_term, (int)max_nonterm
1663 #line 964 "parsegen.pcc"
1665 ------------------------------- Statistics -------------------------------
1666 Merge matching rules = yes
1667 Number of DFA nodes merged = 72
1668 Number of ifs generated = 6
1669 Number of switches generated = 11
1670 Number of labels = 1
1671 Number of gotos = 5
1672 Adaptive matching = enabled
1673 Fast string matching = disabled
1674 Inline downcasts = enabled
1675 --------------------------------------------------------------------------