1 /* Input parser for bison 
   2    Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002 
   3    Free Software Foundation, Inc. 
   5    This file is part of Bison, the GNU Compiler Compiler. 
   7    Bison is free software; you can redistribute it and/or modify 
   8    it under the terms of the GNU General Public License as published by 
   9    the Free Software Foundation; either version 2, or (at your option) 
  12    Bison is distributed in the hope that it will be useful, 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15    GNU General Public License for more details. 
  17    You should have received a copy of the GNU General Public License 
  18    along with Bison; see the file COPYING.  If not, write to 
  19    the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  20    Boston, MA 02111-1307, USA.  */ 
  34 #include "conflicts.h" 
  35 #include "muscle_tab.h" 
  37 static symbol_list_t 
*grammar 
= NULL
; 
  38 static int start_flag 
= 0; 
  39 merger_list 
*merge_functions
; 
  41 /* Nonzero if %union has been seen.  */ 
  44 /*-----------------------. 
  45 | Set the start symbol.  | 
  46 `-----------------------*/ 
  49 grammar_start_symbol_set (symbol_t 
*s
, location_t l
) 
  52     complain_at (l
, _("multiple %s declarations"), "%start"); 
  57       startsymbol_location 
= l
; 
  62 /*----------------------------------------------------------------. 
  63 | There are two prologues: one before %union, one after.  Augment | 
  65 `----------------------------------------------------------------*/ 
  68 prologue_augment (const char *prologue
, location_t location
) 
  70   struct obstack 
*oout 
= 
  71     !typed 
? &pre_prologue_obstack 
: &post_prologue_obstack
; 
  75       obstack_fgrow2 (oout
, muscle_find ("linef"), 
  77                       quotearg_style (c_quoting_style
, 
  78                                       muscle_find ("filename"))); 
  80   obstack_sgrow (oout
, prologue
); 
  86 /*----------------------. 
  87 | Handle the epilogue.  | 
  88 `----------------------*/ 
  91 epilogue_set (const char *epilogue
, location_t location
) 
  95       obstack_fgrow2 (&muscle_obstack
, muscle_find ("linef"), 
  97                       quotearg_style (c_quoting_style
, 
  98                                       muscle_find ("filename"))); 
 100   obstack_sgrow (&muscle_obstack
, epilogue
); 
 101   obstack_1grow (&muscle_obstack
, 0); 
 102   muscle_insert ("epilogue", obstack_finish (&muscle_obstack
)); 
 108  /*-------------------------------------------------------------------. 
 109 | Return the merger index for a merging function named NAME, whose   | 
 110 | arguments have type TYPE.  Records the function, if new, in        | 
 112 `-------------------------------------------------------------------*/ 
 115 get_merge_function (const char* name
, const char* type
, 
 128   head
.next 
= merge_functions
; 
 129   for (syms 
= &head
, n 
= 1; syms
->next 
!= NULL
; syms 
= syms
->next
, n 
+= 1) 
 130     if (strcmp (name
, syms
->next
->name
) == 0) 
 132   if (syms
->next 
== NULL
) 
 134       syms
->next 
= XMALLOC (merger_list
, 1); 
 135       syms
->next
->name 
= xstrdup (name
); 
 136       syms
->next
->type 
= xstrdup (type
); 
 137       syms
->next
->next 
= NULL
; 
 138       merge_functions 
= head
.next
; 
 140   else if (strcmp (type
, syms
->next
->type
) != 0) 
 141     warn_at (loc
, _("result type clash on merge function %s: `%s' vs. `%s'"), 
 142              name
, type
, syms
->next
->type
); 
 146 /*--------------------------------------. 
 147 | Free all merge-function definitions.  | 
 148 `--------------------------------------*/ 
 151 free_merger_functions (void) 
 156   L0 
= merge_functions
; 
 159       merger_list 
*L1 
= L0
->next
; 
 166 /*-------------------------------------------------------------------. 
 167 | Parse the input grammar into a one symbol_list_t structure.  Each  | 
 168 | rule is represented by a sequence of symbols: the left hand side   | 
 169 | followed by the contents of the right hand side, followed by a     | 
 170 | null pointer instead of a symbol to terminate the rule.  The next  | 
 171 | symbol is the lhs of the following rule.                           | 
 173 | All actions are copied out, labelled by the rule number they apply | 
 176 | Bison used to allow some %directives in the rules sections, but    | 
 177 | this is no longer consider appropriate: (i) the documented grammar | 
 178 | doesn't claim it, (ii), it would promote bad style, (iii), error   | 
 179 | recovery for %directives consists in skipping the junk until a `%' | 
 180 | is seen and helrp synchronizing.  This scheme is definitely wrong  | 
 181 | in the rules section.                                              | 
 182 `-------------------------------------------------------------------*/ 
 184 /* The (currently) last symbol of GRAMMAR. */ 
 185 symbol_list_t 
*grammar_end 
= NULL
; 
 187 /* Append S to the GRAMMAR. */ 
 189 grammar_symbol_append (symbol_t 
*symbol
, location_t location
) 
 191   symbol_list_t 
*p 
= symbol_list_new (symbol
, location
); 
 194     grammar_end
->next 
= p
; 
 201 /* The rule currently being defined, and the previous rule. 
 202    CURRENT_RULE points to the first LHS of the current rule, while 
 203    PREVIOUS_RULE_END points to the *end* of the previous rule (NULL).  */ 
 204 symbol_list_t 
*current_rule 
= NULL
; 
 205 symbol_list_t 
*previous_rule_end 
= NULL
; 
 208 /*----------------------------------------------. 
 209 | Create a new rule for LHS in to the GRAMMAR.  | 
 210 `----------------------------------------------*/ 
 213 grammar_rule_begin (symbol_t 
*lhs
, location_t location
) 
 218       startsymbol_location 
= location
; 
 222   /* Start a new rule and record its lhs.  */ 
 226   previous_rule_end 
= grammar_end
; 
 227   grammar_symbol_append (lhs
, location
); 
 228   current_rule 
= grammar_end
; 
 230   /* Mark the rule's lhs as a nonterminal if not already so.  */ 
 232   if (lhs
->class == unknown_sym
) 
 234       lhs
->class = nterm_sym
; 
 238   else if (lhs
->class == token_sym
) 
 239     complain_at (location
, _("rule given for %s, which is a token"), lhs
->tag
); 
 242 /* Check that the last rule (CURRENT_RULE) is properly defined.  For 
 243    instance, there should be no type clash on the default action.  */ 
 246 grammar_current_rule_check (void) 
 248   symbol_t 
*lhs 
= current_rule
->sym
; 
 249   char const *lhs_type 
= lhs
->type_name
; 
 250   symbol_t 
*first_rhs 
= current_rule
->next
->sym
; 
 252   /* If there is an action, then there is nothing we can do: the user 
 253      is allowed to shoot herself in the foot.  */ 
 254   if (current_rule
->action
) 
 257   /* Don't worry about the default action if $$ is untyped, since $$'s 
 258      value can't be used.  */ 
 262   /* If $$ is being set in default way, report if any type mismatch.  */ 
 265       const char *rhs_type 
= first_rhs
->type_name 
? first_rhs
->type_name 
: ""; 
 266       if (strcmp (lhs_type
, rhs_type
)) 
 267         complain_at (current_rule
->location
, 
 268                      _("type clash (`%s' `%s') on default action"), 
 271   /* Warn if there is no default for $$ but we need one.  */ 
 273     complain_at (current_rule
->location
, 
 274                  _("empty rule for typed nonterminal, and no action")); 
 278 /*-------------------------------------. 
 279 | End the currently being grown rule.  | 
 280 `-------------------------------------*/ 
 283 grammar_rule_end (location_t location
) 
 285   /* Put an empty link in the list to mark the end of this rule  */ 
 286   grammar_symbol_append (NULL
, grammar_end
->location
); 
 287   current_rule
->location 
= location
; 
 288   grammar_current_rule_check (); 
 292 /*-------------------------------------------------------------------. 
 293 | The previous action turns out the be a mid-rule action.  Attach it | 
 294 | to the current rule, i.e., create a dummy symbol, attach it this   | 
 295 | mid-rule action, and append this dummy nonterminal to the current  | 
 297 `-------------------------------------------------------------------*/ 
 300 grammar_midrule_action (void) 
 302   /* Since the action was written out with this rule's number, we must 
 303      give the new rule this number by inserting the new rule before 
 306   /* Make a DUMMY nonterminal, whose location is that of the midrule 
 307      action.  Create the MIDRULE.  */ 
 308   location_t dummy_location 
= current_rule
->action_location
; 
 309   symbol_t 
*dummy 
= dummy_symbol_get (dummy_location
); 
 310   symbol_list_t 
*midrule 
= symbol_list_new (dummy
, dummy_location
); 
 312   /* Make a new rule, whose body is empty, before the current one, so 
 313      that the action just read can belong to it.  */ 
 316   /* Attach its location and actions to that of the DUMMY.  */ 
 317   midrule
->location 
= dummy_location
; 
 318   midrule
->action 
= current_rule
->action
; 
 319   midrule
->action_location 
= dummy_location
; 
 320   current_rule
->action 
= NULL
; 
 322   if (previous_rule_end
) 
 323     previous_rule_end
->next 
= midrule
; 
 327   /* End the dummy's rule.  */ 
 328   previous_rule_end 
= symbol_list_new (NULL
, dummy_location
); 
 329   previous_rule_end
->next 
= current_rule
; 
 331   midrule
->next 
= previous_rule_end
; 
 333   /* Insert the dummy nonterminal replacing the midrule action into 
 335   grammar_current_rule_symbol_append (dummy
, dummy_location
); 
 338 /* Set the precedence symbol of the current rule to PRECSYM. */ 
 341 grammar_current_rule_prec_set (symbol_t 
*precsym
, location_t location
) 
 343   if (current_rule
->ruleprec
) 
 344     complain_at (location
, _("only one %s allowed per rule"), "%prec"); 
 345   current_rule
->ruleprec 
= precsym
; 
 348 /* Attach dynamic precedence DPREC to the current rule. */ 
 351 grammar_current_rule_dprec_set (int dprec
, location_t location
) 
 354     warn_at (location
, _("%s affects only GLR parsers"), "%dprec"); 
 356     complain_at (location
, 
 357                  _("%s must be followed by positive number"), "%dprec"); 
 358   else if (current_rule
->dprec 
!= 0) 
 359     complain_at (location
, _("only one %s allowed per rule"), "%dprec"); 
 360   current_rule
->dprec 
= dprec
; 
 363 /* Attach a merge function NAME with argument type TYPE to current 
 367 grammar_current_rule_merge_set (const char* name
, location_t location
) 
 370     warn_at (location
, _("%s affects only GLR parsers"), "%merge"); 
 371   if (current_rule
->merger 
!= 0) 
 372     complain_at (location
, _("only one %s allowed per rule"), "%merge"); 
 373   current_rule
->merger 
= 
 374     get_merge_function (name
, current_rule
->sym
->type_name
, location
); 
 377 /* Attach a SYMBOL to the current rule.  If needed, move the previous 
 378    action as a mid-rule action.  */ 
 381 grammar_current_rule_symbol_append (symbol_t 
*symbol
, location_t location
) 
 383   if (current_rule
->action
) 
 384     grammar_midrule_action (); 
 386   grammar_symbol_append (symbol
, location
); 
 389 /* Attach an ACTION to the current rule.  If needed, move the previous 
 390    action as a mid-rule action.  */ 
 393 grammar_current_rule_action_append (const char *action
, location_t location
) 
 395   if (current_rule
->action
) 
 396     grammar_midrule_action (); 
 397   current_rule
->action 
= action
; 
 398   current_rule
->action_location 
= location
; 
 402 /*---------------------------------------------------------------. 
 403 | Convert the rules into the representation using RRHS, RLHS and | 
 405 `---------------------------------------------------------------*/ 
 410   unsigned int itemno 
= 0; 
 411   rule_number_t ruleno 
= 0; 
 412   symbol_list_t 
*p 
= grammar
; 
 414   ritem 
= XCALLOC (item_number_t
, nritems
); 
 415   rules 
= XCALLOC (rule_t
, nrules
); 
 419       symbol_t 
*ruleprec 
= p
->ruleprec
; 
 420       rules
[ruleno
].user_number 
= ruleno
; 
 421       rules
[ruleno
].number 
= ruleno
; 
 422       rules
[ruleno
].lhs 
= p
->sym
; 
 423       rules
[ruleno
].rhs 
= ritem 
+ itemno
; 
 424       rules
[ruleno
].location 
= p
->location
; 
 425       rules
[ruleno
].useful 
= true; 
 426       rules
[ruleno
].action 
= p
->action
; 
 427       rules
[ruleno
].action_location 
= p
->action_location
; 
 428       rules
[ruleno
].dprec 
= p
->dprec
; 
 429       rules
[ruleno
].merger 
= p
->merger
; 
 434           /* item_number_t = symbol_number_t. 
 435              But the former needs to contain more: negative rule numbers. */ 
 436           ritem
[itemno
++] = symbol_number_as_item_number (p
->sym
->number
); 
 437           /* A rule gets by default the precedence and associativity 
 438              of the last token in it.  */ 
 439           if (p
->sym
->class == token_sym
) 
 440             rules
[ruleno
].prec 
= p
->sym
; 
 445       /* If this rule has a %prec, 
 446          the specified symbol's precedence replaces the default.  */ 
 449           rules
[ruleno
].precsym 
= ruleprec
; 
 450           rules
[ruleno
].prec 
= ruleprec
; 
 452       ritem
[itemno
++] = rule_number_as_item_number (ruleno
); 
 459   assert (itemno 
== nritems
); 
 461   if (trace_flag 
& trace_sets
) 
 462     ritem_print (stderr
); 
 465 /*------------------------------------------------------------------. 
 466 | Read in the grammar specification and record it in the format     | 
 467 | described in gram.h.  All actions are copied into ACTION_OBSTACK, | 
 468 | in each case forming the body of a C function (YYACTION) which    | 
 469 | contains a switch statement to decide which action to execute.    | 
 470 `------------------------------------------------------------------*/ 
 475   gram_control_t gram_control
; 
 477   /* Initialize the symbol table.  */ 
 480   /* Construct the accept symbol. */ 
 481   accept 
= symbol_get ("$accept", empty_location
); 
 482   accept
->class = nterm_sym
; 
 483   accept
->number 
= nvars
++; 
 485   /* Construct the error token */ 
 486   errtoken 
= symbol_get ("error", empty_location
); 
 487   errtoken
->class = token_sym
; 
 488   errtoken
->number 
= ntokens
++; 
 490   /* Construct a token that represents all undefined literal tokens. 
 491      It is always token number 2.  */ 
 492   undeftoken 
= symbol_get ("$undefined", empty_location
); 
 493   undeftoken
->class = token_sym
; 
 494   undeftoken
->number 
= ntokens
++; 
 496   /* Initialize the obstacks. */ 
 497   obstack_init (&pre_prologue_obstack
); 
 498   obstack_init (&post_prologue_obstack
); 
 500   finput 
= xfopen (infile
, "r"); 
 503   gram__flex_debug 
= trace_flag 
& trace_scan
; 
 504   gram_debug 
= trace_flag 
& trace_parse
; 
 505   scanner_initialize (); 
 506   gram_parse (&gram_control
); 
 508   /* If something went wrong during the parsing, don't try to 
 510   if (complaint_issued
) 
 513   /* Grammar has been read.  Do some checking */ 
 515     fatal (_("no rules in the input grammar")); 
 517   /* Report any undefined symbols and consider them nonterminals.  */ 
 518   symbols_check_defined (); 
 520   /* If the user did not define her ENDTOKEN, do it now. */ 
 523       endtoken 
= symbol_get ("$end", empty_location
); 
 524       endtoken
->class = token_sym
; 
 525       endtoken
->number 
= 0; 
 526       /* Value specified by POSIX.  */ 
 527       endtoken
->user_token_number 
= 0; 
 530   /* Insert the initial rule, which line is that of the first rule 
 531      (not that of the start symbol): 
 533      accept: %start EOF.  */ 
 535     symbol_list_t 
*p 
= symbol_list_new (accept
, empty_location
); 
 536     p
->location 
= grammar
->location
; 
 537     p
->next 
= symbol_list_new (startsymbol
, empty_location
); 
 538     p
->next
->next 
= symbol_list_new (endtoken
, empty_location
); 
 539     p
->next
->next
->next 
= symbol_list_new (NULL
, empty_location
); 
 540     p
->next
->next
->next
->next 
= grammar
; 
 546   if (SYMBOL_NUMBER_MAX 
< nsyms
) 
 547     fatal (_("too many symbols (tokens plus nonterminals); maximum %d"), 
 550   assert (nsyms 
== ntokens 
+ nvars
); 
 554   /* Assign the symbols their symbol numbers.  Write #defines for the 
 555      token symbols into FDEFINES if requested.  */ 
 558   /* Convert the grammar into the format described in gram.h.  */ 
 561   /* The grammar as a symbol_list_t is no longer needed. */ 
 562   LIST_FREE (symbol_list_t
, grammar
);