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
9 ///////////////////////////////////////////////////////////////////////////////
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 ///////////////////////////////////////////////////////////////////////////////
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>
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"
393 case a_ProductionSymbol::tag_TERMSTRINGsym
: {
394 #line 59 "parsegen.pcc"
395 f
<< ((ProductionSymbol_TERMSTRINGsym
*)sym
)->TERMSTRINGsym
;
396 #line 59 "parsegen.pcc"
398 case a_ProductionSymbol::tag_TERMREGEXPsym
: {
399 #line 60 "parsegen.pcc"
400 f
<< ((ProductionSymbol_TERMREGEXPsym
*)sym
)->TERMREGEXPsym
;
401 #line 60 "parsegen.pcc"
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"
409 #line 54 "parsegen.pcc"
411 #line 54 "parsegen.pcc"
414 case a_ProductionSymbol::tag_NONTERMsym
: {
415 #line 56 "parsegen.pcc"
416 f
<< ((ProductionSymbol_NONTERMsym
*)sym
)->NONTERMsym
;
417 #line 56 "parsegen.pcc"
419 case a_ProductionSymbol::tag_POSNONTERMsym
: {
420 #line 57 "parsegen.pcc"
421 f
<< ((ProductionSymbol_POSNONTERMsym
*)sym
)->POSNONTERMsym
;
422 #line 57 "parsegen.pcc"
424 case a_ProductionSymbol::tag_ACTIONsym
: {
425 #line 58 "parsegen.pcc"
427 #line 58 "parsegen.pcc"
429 case a_ProductionSymbol::tag_PREDICATEsym
: {
430 #line 61 "parsegen.pcc"
431 f
<< '(' << ((ProductionSymbol_PREDICATEsym
*)sym
)->PREDICATEsym
<< ')';
432 #line 61 "parsegen.pcc"
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"
440 #line 63 "parsegen.pcc"
442 #line 63 "parsegen.pcc"
445 case a_ProductionSymbol::tag_ERRORsym
: {
446 #line 64 "parsegen.pcc"
448 #line 64 "parsegen.pcc"
451 #line 65 "parsegen.pcc"
453 #line 65 "parsegen.pcc"
457 #line 66 "parsegen.pcc"
458 #line 66 "parsegen.pcc"
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
<< " "; }
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"
486 if (bnf
->_2
!= NOty
) f
<< ' ' << bnf
->_2
<< ' ';
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"
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
;
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
;
527 #line 118 "parsegen.pcc"
529 #line 118 "parsegen.pcc"
532 #line 119 "parsegen.pcc"
534 #line 119 "parsegen.pcc"
537 #line 120 "parsegen.pcc"
539 #line 120 "parsegen.pcc"
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"
556 ///////////////////////////////////////////////////////////////////////////////
558 // Print a list of precedence rules
560 ///////////////////////////////////////////////////////////////////////////////
561 std::ostream
& operator << (std::ostream
& f
,
562 #line 133 "parsegen.pcc"
564 #line 133 "parsegen.pcc"
566 { for_each (PrecRule
, r
, rules
) f
<< r
;
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"
588 #line 147 "parsegen.pcc"
589 #line 147 "parsegen.pcc"
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"
605 #line 158 "parsegen.pcc"
606 #line 158 "parsegen.pcc"
607 ,add_inherit("LR1Parser",
608 #line 158 "parsegen.pcc"
609 #line 158 "parsegen.pcc"
611 #line 158 "parsegen.pcc"
612 #line 158 "parsegen.pcc"
615 #line 159 "parsegen.pcc"
616 #line 159 "parsegen.pcc"
618 #line 159 "parsegen.pcc"
619 #line 159 "parsegen.pcc"
622 #line 160 "parsegen.pcc"
623 #line 160 "parsegen.pcc"
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
)
647 "%^// Parser table type definitions"
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"
662 "%^// Semantic value stack"
664 "%^union %s_semantic_stack_type * t__, * bot__;"
665 "%^int stack_size__;"
666 "%^int heap_allocated__;"
669 "%^// Constructor and parsing method"
672 "%^virtual void parse();"
673 "%^void action_driver(const Rule);"
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
)
702 compile_grammar(C
, e
);
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"
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"
724 #line 250 "parsegen.pcc"
725 bug("SyntaxClass::compile_grammar");
726 #line 250 "parsegen.pcc"
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
)
758 #line 273 "parsegen.pcc"
759 #line 285 "parsegen.pcc"
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"
783 default: { goto L1
; } break;
788 case a_ProductionSymbol::tag_ACTIONsym
: {
789 #line 283 "parsegen.pcc"
791 #line 283 "parsegen.pcc"
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
))
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
)
861 int non_terms_or_actions
= 0;
863 Grammar::Production P
=
864 (Grammar::Production
)mem_pool
.c_alloc
865 (sizeof(Grammar::Symbol
) * (length(p
) + 2));
868 #line 340 "parsegen.pcc"
869 a_List
<ProductionSymbol
> *
870 #line 340 "parsegen.pcc"
872 { ProductionSymbol X
= L
->_1
;
875 #line 373 "parsegen.pcc"
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"
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"
906 #line 360 "parsegen.pcc"
908 #line 360 "parsegen.pcc"
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
); }
916 { P
[j
] = (Grammar::NonTerminal
)nonterm_map
[((ProductionSymbol_NONTERMsym
*)X
)->NONTERMsym
]; }
917 ++non_terms_or_actions
;
919 #line 355 "parsegen.pcc"
921 case a_ProductionSymbol::tag_ACTIONsym
: {
922 #line 362 "parsegen.pcc"
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
));
928 #line 366 "parsegen.pcc"
929 #line 366 "parsegen.pcc"
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
));
937 ++non_terms_or_actions
;
939 #line 371 "parsegen.pcc"
941 case a_ProductionSymbol::tag_ERRORsym
: {
942 #line 372 "parsegen.pcc"
944 #line 372 "parsegen.pcc"
947 #line 373 "parsegen.pcc"
948 bug("translate_into_grammar()");
949 #line 373 "parsegen.pcc"
953 #line 374 "parsegen.pcc"
954 #line 374 "parsegen.pcc"
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
;
990 #line 396 "parsegen.pcc"
991 a
= OpPrecedence::Left
;
992 #line 396 "parsegen.pcc"
995 #line 397 "parsegen.pcc"
996 a
= OpPrecedence::Right
;
997 #line 397 "parsegen.pcc"
1000 #line 398 "parsegen.pcc"
1001 a
= OpPrecedence::None
;
1002 #line 398 "parsegen.pcc"
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"
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"
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"
1030 #line 411 "parsegen.pcc"
1032 error("%Lprecedence symbol must be a terminal: ")
1035 #line 414 "parsegen.pcc"
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
);
1061 #line 430 "parsegen.pcc"
1063 #line 430 "parsegen.pcc"
1064 old_uses
= (a_List
<int> *
1065 #line 430 "parsegen.pcc"
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"
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 ////////////////////////////////////////////////////////////////////////////
1101 "%^// Semantic value stack for syntax class %s"
1103 "%^union %s_semantic_stack_type {%+"
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
);
1121 { Ty last_ty
= (Ty
)nonterm_to_ty
.value(e
);
1122 if (! ty_equal(rl
->_2
,last_ty
))
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
)
1152 add_use(nonterm_to_uses
,r
->_1
,item_number
);
1153 for_each (ProductionSymbol
, X
, p
)
1156 #line 498 "parsegen.pcc"
1157 #line 508 "parsegen.pcc"
1160 case a_ProductionSymbol::tag_NONTERMsym
: {
1161 #line 500 "parsegen.pcc"
1162 HashTable::Entry
* e
= nonterm_to_ty
.lookup(((ProductionSymbol_NONTERMsym
*)X
)->NONTERMsym
);
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"
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
1192 ////////////////////////////////////////////////////////////////////////////
1194 for_each (BNF
, r
, production_rules
)
1196 #line 523 "parsegen.pcc"
1197 #line 538 "parsegen.pcc"
1199 #line 525 "parsegen.pcc"
1202 #line 526 "parsegen.pcc"
1204 #line 526 "parsegen.pcc"
1205 uses
= (a_List
<int> *
1206 #line 526 "parsegen.pcc"
1207 )nonterm_to_uses
[r
->_1
];
1209 #line 527 "parsegen.pcc"
1211 #line 527 "parsegen.pcc"
1212 #line 527 "parsegen.pcc"
1215 "%^typedef %tATTRIBUTE_%i;"
1217 r
->begin_line
, r
->file_name
, r
->_2
, "", i
, i
);
1219 #line 532 "parsegen.pcc"
1221 #line 532 "parsegen.pcc"
1222 l
= uses
; l
; l
= l
->_2
)
1223 { C
.pr ("_%i", l
->_1
); if (l
->_2
) C
.pr(", "); }
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
)
1245 "%^// Debugging tables for syntax class %s"
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
);
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[] = { ",
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
]); }
1296 { C
.pr ("%^static const DFATables::ShortSymbol * %s_rhs[] =%^{%+",
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 ////////////////////////////////////////////////////////////////////////////
1318 "%^// Encoded parser tables for syntax class %s"
1321 parserGen
->gen_code(C
.pr(""),class_name
);
1324 void SyntaxClass::generate_action_driver(CodeGen
& C
)
1326 ////////////////////////////////////////////////////////////////////////////
1328 // Generate the parser driver header.
1330 ////////////////////////////////////////////////////////////////////////////
1333 "%^// Parser driver for syntax class %s"
1335 "%^inline void %s::action_driver(const Rule _r_)"
1337 "%^%s_semantic_stack_type syn_;",
1338 class_name
, class_name
, class_name
1341 ////////////////////////////////////////////////////////////////////////////
1342 // Generate the debugging function
1343 ////////////////////////////////////////////////////////////////////////////
1345 "%^// Tracing code for syntax class %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_] << ' ';"
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
);
1365 ///////////////////////////////////////////////////////////////////////////////
1367 // Generate the parse method
1369 ///////////////////////////////////////////////////////////////////////////////
1370 void SyntaxClass::generate_parse_method(CodeGen
& C
)
1373 "%^// Parsing method for parser class %s"
1375 "%^void %s::parse()"
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__;"
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 ////////////////////////////////////////////////////////////////////////////
1403 "%^// Actions for syntax class %s"
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 ////////////////////////////////////////////////////////////////////////////
1417 for (Grammar::Action a
= Grammar::First_action
; a
> min_action
; a
--)
1418 { HashTable::Entry
* e
= inner_action_map
.lookup(HashTable::Key(a
));
1426 C
.pr ("%^case %i: {%+%&%-} break;",
1427 (int)G
->rule_of(a
), action_map
[HashTable::Key(a
)]);
1436 "%^if (t__ >= bot__ + stack_size__) grow_semantic_stack();"
1441 ///////////////////////////////////////////////////////////////////////////////
1443 // Method to initialize the data structures
1445 ///////////////////////////////////////////////////////////////////////////////
1446 void SyntaxClass::initialize()
1448 number_of_productions
= 0;
1454 min_action
= Grammar::First_action
;
1463 ///////////////////////////////////////////////////////////////////////////////
1465 // Method to cleanup all the data structures
1467 ///////////////////////////////////////////////////////////////////////////////
1468 void SyntaxClass::cleanup()
1470 nonterm_map
.clear();
1472 inner_action_map
.clear();
1474 predicate_map
.clear();
1483 ///////////////////////////////////////////////////////////////////////////////
1485 // Method to compile a set of production rules
1487 ///////////////////////////////////////////////////////////////////////////////
1488 void SyntaxClass::compile_rules
1490 PrecRules prec_rules
,
1491 ShiftReduceErrors expected_errors
,
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 ////////////////////////////////////////////////////////////////////////////
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"
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 ",
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
)
1621 "%^void %s::grow_semantic_stack()\n"
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__);"
1631 "%^stack_size__ = N - 1;"
1632 "%^heap_allocated__ = 1;"
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",
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
)
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
1672 Adaptive matching = enabled
1673 Fast string matching = disabled
1674 Inline downcasts = enabled
1675 --------------------------------------------------------------------------