1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/* Input parser for Bison
2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007,
4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   2009-2012 Free Software Foundation, Inc.
5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   This file is part of Bison, the GNU Compiler Compiler.
7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   This program is free software: you can redistribute it and/or modify
9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   it under the terms of the GNU General Public License as published by
10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   the Free Software Foundation, either version 3 of the License, or
11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   (at your option) any later version.
12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   This program is distributed in the hope that it will be useful,
14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   but WITHOUT ANY WARRANTY; without even the implied warranty of
15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
164fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune   GNU General Public License for more details.
17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
1858a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth   You should have received a copy of the GNU General Public License
19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard
21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include <config.h>
22c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include "system.h"
235c35290fa35ae234fed02496404cb0fc37e1c8a5Benjamin Kramer
24c0b0c677a1138f0a5ce1435fc1e70cef38fd95c8Tom Stellard#include <quote.h>
25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "complain.h"
27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "conflicts.h"
28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "files.h"
29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "getargs.h"
30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "gram.h"
31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "muscle-tab.h"
32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "reader.h"
33b5632b5b456db647b42239cbd4d8b58c82290c4eBill Wendling#include "symlist.h"
34631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune#include "symtab.h"
35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "scan-gram.h"
36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "scan-code.h"
37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic void prepare_percent_define_front_end_variables (void);
39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic void check_and_convert_grammar (void);
40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic symbol_list *grammar = NULL;
42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic bool start_flag = false;
43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardmerger_list *merge_functions;
44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/* Was %union seen?  */
46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool union_seen = false;
47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/* Was a tag seen?  */
49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool tag_seen = false;
50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/* Should rules have a default precedence?  */
52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardbool default_prec = true;
53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
54692ee102ebef535d311c35d53457028083e5c5beTom Stellard/*-----------------------.
55692ee102ebef535d311c35d53457028083e5c5beTom Stellard| Set the start symbol.  |
56692ee102ebef535d311c35d53457028083e5c5beTom Stellard`-----------------------*/
57692ee102ebef535d311c35d53457028083e5c5beTom Stellard
58692ee102ebef535d311c35d53457028083e5c5beTom Stellardvoid
59692ee102ebef535d311c35d53457028083e5c5beTom Stellardgrammar_start_symbol_set (symbol *sym, location loc)
60692ee102ebef535d311c35d53457028083e5c5beTom Stellard{
61692ee102ebef535d311c35d53457028083e5c5beTom Stellard  if (start_flag)
62692ee102ebef535d311c35d53457028083e5c5beTom Stellard    complain_at (loc, _("multiple %s declarations"), "%start");
63692ee102ebef535d311c35d53457028083e5c5beTom Stellard  else
64692ee102ebef535d311c35d53457028083e5c5beTom Stellard    {
65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      start_flag = true;
66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      startsymbol = sym;
67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      startsymbol_location = loc;
68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
69f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/*------------------------------------------------------------------------.
74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| Return the merger index for a merging function named NAME.  Records the |
755e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard| function, if new, in MERGER_LIST.                                       |
76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard`------------------------------------------------------------------------*/
77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic int
79f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardget_merge_function (uniqstr name)
80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard{
81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  merger_list *syms;
82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  merger_list head;
836b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi  int n;
846b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi
856b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi  if (! glr_parser)
866b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi    return 0;
876b207d3cfa6b7be87ebde25c6c002f776f3d1595NAKAMURA Takumi
88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  head.next = merge_functions;
89f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (UNIQSTR_EQ (name, syms->next->name))
91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      break;
92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (syms->next == NULL)
93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    {
94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      syms->next = xmalloc (sizeof syms->next[0]);
95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      syms->next->name = uniqstr_new (name);
96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      /* After all symbol type declarations have been parsed, packgram invokes
97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard	 record_merge_function_type to set the type.  */
98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      syms->next->type = NULL;
99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      syms->next->next = NULL;
100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      merge_functions = head.next;
101f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
102f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  return n;
103f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
104f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
105f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/*-------------------------------------------------------------------------.
106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| For the existing merging function with index MERGER, record the result   |
107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| type as TYPE as required by the lhs of the rule whose %merge declaration |
108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| is at DECLARATION_LOC.                                                   |
109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard`-------------------------------------------------------------------------*/
110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic void
112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardrecord_merge_function_type (int merger, uniqstr type, location declaration_loc)
113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard{
114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  int merger_find;
115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  merger_list *merge_function;
116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (merger <= 0)
118f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    return;
119f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
12080095e5f8e433b7a68fbad4ff460503fd06f84efAaron Ballman  if (type == NULL)
121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    type = uniqstr_new ("");
122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  merger_find = 1;
124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  for (merge_function = merge_functions;
125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard       merge_function != NULL && merger_find != merger;
126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard       merge_function = merge_function->next)
127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    merger_find += 1;
128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  aver (merge_function != NULL && merger_find == merger);
129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    {
131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      unsigned indent = 0;
132f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      complain_at_indent (declaration_loc, &indent,
133f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                          _("result type clash on merge function %s: "
134f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                            "<%s> != <%s>"),
135f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                          quote (merge_function->name), type,
136f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                          merge_function->type);
1377e9381951eb4dadf9c59257786416ac51a6a6c09Tom Stellard      indent += SUB_INDENT;
138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      complain_at_indent (merge_function->type_declaration_location, &indent,
139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard                          _("previous declaration"));
140e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard   }
141e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  merge_function->type = uniqstr_new (type);
142e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  merge_function->type_declaration_location = declaration_loc;
143e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard}
144e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
145e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard/*--------------------------------------.
146e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard| Free all merge-function definitions.	|
147e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard`--------------------------------------*/
148e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
149e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardvoid
150e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellardfree_merger_functions (void)
151e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard{
152e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  merger_list *L0 = merge_functions;
153e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  while (L0)
154e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    {
155abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune      merger_list *L1 = L0->next;
156af2ea2a4fb785652ec79dbe179c499823ea45f63Tom Stellard      free (L0);
157abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune      L0 = L1;
158abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune    }
159abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune}
160abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune
161abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune
162abcde265b1f8f8d29a4542bfd87ee6f8fb1537a0Vincent Lejeune/*-------------------------------------------------------------------.
163631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune| Parse the input grammar into a one symbol_list structure.  Each    |
16432c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard| rule is represented by a sequence of symbols: the left hand side   |
165631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune| followed by the contents of the right hand side, followed by a     |
166631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune| null pointer instead of a symbol to terminate the rule.  The next  |
167631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune| symbol is the lhs of the following rule.                           |
1684fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune|                                                                    |
1694fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune| All actions are copied out, labelled by the rule number they apply |
170631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune| to.                                                                |
171631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune`-------------------------------------------------------------------*/
172631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune
17332c76107d029c1cad5935d08cdcde6139cf874bbTom Stellard/* The (currently) last symbol of GRAMMAR. */
174631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeunestatic symbol_list *grammar_end = NULL;
175631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune
176631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune/* Append SYM to the grammar.  */
1774fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeunestatic symbol_list *
1784fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeunegrammar_symbol_append (symbol *sym, location loc)
1794fb224e3bd7655e25bc1f43d05a0922098aae4e0Vincent Lejeune{
180631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune  symbol_list *p = symbol_list_sym_new (sym, loc);
181631591e6f3e5119d8a8b1c853279bc4ac7ace4a0Vincent Lejeune
182cedcfee405a22b245e869abe8609f094df34085aTom Stellard  if (grammar_end)
183cedcfee405a22b245e869abe8609f094df34085aTom Stellard    grammar_end->next = p;
184cedcfee405a22b245e869abe8609f094df34085aTom Stellard  else
185cedcfee405a22b245e869abe8609f094df34085aTom Stellard    grammar = p;
186cedcfee405a22b245e869abe8609f094df34085aTom Stellard
187cedcfee405a22b245e869abe8609f094df34085aTom Stellard  grammar_end = p;
188cedcfee405a22b245e869abe8609f094df34085aTom Stellard
189cedcfee405a22b245e869abe8609f094df34085aTom Stellard  /* A null SYM stands for an end of rule; it is not an actual
190cedcfee405a22b245e869abe8609f094df34085aTom Stellard     part of it.  */
191cedcfee405a22b245e869abe8609f094df34085aTom Stellard  if (sym)
19258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    ++nritems;
19358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
19458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  return p;
19558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard}
19658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
19758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardstatic void
19858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardassign_named_ref (symbol_list *p, named_ref *name)
19958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard{
20058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  symbol *sym = p->content.sym;
20158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
20258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  if (name->id == sym->tag)
20358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    {
20458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard      warn_at (name->loc,
20558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard	       _("duplicated symbol name for %s ignored"),
20658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard	       quote (sym->tag));
20758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard      named_ref_free (name);
20858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    }
20958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard  else
21058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard    p->named_ref = name;
21158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard}
21258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
21358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
21458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard/* The rule currently being defined, and the previous rule.
21558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard   CURRENT_RULE points to the first LHS of the current rule, while
21658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard   PREVIOUS_RULE_END points to the *end* of the previous rule (NULL).  */
21758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardstatic symbol_list *current_rule = NULL;
21858d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardstatic symbol_list *previous_rule_end = NULL;
21958d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
22058d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
22158d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard/*----------------------------------------------.
22258d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard| Create a new rule for LHS in to the GRAMMAR.  |
22358d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard`----------------------------------------------*/
22458d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard
22558d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardvoid
22658d3335cb9d2a40bd15c29a12ba045163295190eTom Stellardgrammar_current_rule_begin (symbol *lhs, location loc,
22758d3335cb9d2a40bd15c29a12ba045163295190eTom Stellard			    named_ref *lhs_name)
22825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune{
22925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  symbol_list* p;
23025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
23125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* Start a new rule and record its lhs.  */
232e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune  ++nrules;
2335e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard  previous_rule_end = grammar_end;
2345e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard
2355e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard  p = grammar_symbol_append (lhs, loc);
2365e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard  if (lhs_name)
2375e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard    assign_named_ref (p, named_ref_copy (lhs_name));
2385e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard
2395e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard  current_rule = grammar_end;
2405e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard
2415e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard  /* Mark the rule's lhs as a nonterminal if not already so.  */
242e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune  if (lhs->class == unknown_sym)
243e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune    {
244e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune      lhs->class = nterm_sym;
2455e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard      lhs->number = nvars;
2465e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard      ++nvars;
247e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune    }
248e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune  else if (lhs->class == token_sym)
2495e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard    complain_at (loc, _("rule given for %s, which is a token"), lhs->tag);
2505e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard}
251e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune
252e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune
253e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune/*----------------------------------------------------------------------.
254e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune| A symbol should be used if either:                                    |
255e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune|   1. It has a destructor.                                             |
256e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune|   2. The symbol is a mid-rule symbol (i.e., the generated LHS         |
257e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune|      replacing a mid-rule action) that was assigned to or used, as in |
258e67a4afb5da59c02338622eea68e096ba143113fVincent Lejeune|      "exp: { $$ = 1; } { $$ = $1; }".                                 |
2595e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard`----------------------------------------------------------------------*/
2605e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard
2615e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardstatic bool
2625e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellardsymbol_should_be_used (symbol_list const *s, bool *midrule_warning)
26325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune{
26425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if (symbol_destructor_get (s->content.sym)->code)
26525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    return true;
26625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if ((s->midrule && s->midrule->action_props.is_value_used)
26725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      || (s->midrule_parent_rule
26825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune          && symbol_list_n_get (s->midrule_parent_rule,
26925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune                                s->midrule_parent_rhs_index)
27025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune               ->action_props.is_value_used))
27125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    {
27225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      *midrule_warning = true;
27325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      return true;
27425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    }
27525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  return false;
27625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune}
27725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
27825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune/*----------------------------------------------------------------.
2795e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard| Check that the rule R is properly defined.  For instance, there |
28025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune| should be no type clash on the default action.                  |
28125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune`----------------------------------------------------------------*/
28225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
28325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunestatic void
28425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunegrammar_rule_check (const symbol_list *r)
28525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune{
28625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* Type check.
28725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
28825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     If there is an action, then there is nothing we can do: the user
28925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     is allowed to shoot herself in the foot.
2908f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
2918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     Don't worry about the default action if $$ is untyped, since $$'s
2928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     value can't be used.  */
29325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if (!r->action_props.code && r->content.sym->type_name)
29425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    {
29525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      symbol *first_rhs = r->next->content.sym;
29625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      /* If $$ is being set in default way, report if any type mismatch.  */
29725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      if (first_rhs)
29825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	{
29925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	  char const *lhs_type = r->content.sym->type_name;
300e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard	  const char *rhs_type =
301e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard	    first_rhs->type_name ? first_rhs->type_name : "";
302e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard	  if (!UNIQSTR_EQ (lhs_type, rhs_type))
3038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune	    warn_at (r->location,
3048f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune		     _("type clash on default action: <%s> != <%s>"),
3058f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune		     lhs_type, rhs_type);
30625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	}
30725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      /* Warn if there is no default for $$ but we need one.  */
3088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      else
3098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune	warn_at (r->location,
31025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune		 _("empty rule for typed nonterminal, and no action"));
31125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    }
31225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
3138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* Check that symbol values that should be used are in fact used.  */
31425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  {
31525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    symbol_list const *l = r;
31625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    int n = 0;
31725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    for (; l && l->content.sym; l = l->next, ++n)
31825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      {
31925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune        bool midrule_warning = false;
32025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune        if (!l->action_props.is_value_used
32125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune            && symbol_should_be_used (l, &midrule_warning)
32225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune            /* The default action, $$ = $1, `uses' both.  */
32325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune            && (r->action_props.code || (n != 0 && n != 1)))
32425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune          {
3257d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune            void (*warn_at_ptr)(location, char const*, ...) =
32625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune              midrule_warning ? midrule_value_at : warn_at;
3277d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune            if (n)
32825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune              warn_at_ptr (l->location, _("unused value: $%d"), n);
32925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune            else
3307d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune              warn_at_ptr (l->location, _("unset value: $$"));
33125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune          }
33225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      }
3337d1a0d4e3ebf058a8b1d0dea9b6119444ed041c8Vincent Lejeune  }
33425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
33525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* See comments in grammar_current_rule_prec_set for how POSIX
33625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     mandates this complaint.  It's only for identifiers, so skip
33725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     it for char literals and strings, which are always tokens.  */
33825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if (r->ruleprec
33925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
34025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      && !r->ruleprec->declared && !r->ruleprec->prec)
34125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    warn_at (r->location, _("token for %%prec is not defined: %s"),
34225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune             r->ruleprec->tag);
34325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune}
34425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
34525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
34625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune/*-------------------------------------.
34725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune| End the currently being grown rule.  |
3488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune`-------------------------------------*/
3498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
3518f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_current_rule_end (location loc)
3528f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune{
3538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* Put an empty link in the list to mark the end of this rule  */
3548f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  grammar_symbol_append (NULL, grammar_end->location);
3558f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  current_rule->location = loc;
3568f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
3578f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3588f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3598f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/*-------------------------------------------------------------------.
3608f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune| The previous action turns out the be a mid-rule action.  Attach it |
3618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune| to the current rule, i.e., create a dummy symbol, attach it this   |
3628f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune| mid-rule action, and append this dummy nonterminal to the current  |
3638f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune| rule.                                                              |
3648f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune`-------------------------------------------------------------------*/
3658f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3668f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
3678f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_midrule_action (void)
3688f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune{
3698f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* Since the action was written out with this rule's number, we must
3708f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     give the new rule this number by inserting the new rule before
3718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     it.  */
3728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* Make a DUMMY nonterminal, whose location is that of the midrule
3748f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     action.  Create the MIDRULE.  */
3758f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  location dummy_location = current_rule->action_props.location;
3768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  symbol *dummy = dummy_symbol_get (dummy_location);
3778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
3788f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
3798f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* Remember named_ref of previous action. */
3808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  named_ref *action_name = current_rule->action_props.named_ref;
38125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
38225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* Make a new rule, whose body is empty, before the current one, so
3838f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     that the action just read can belong to it.  */
38425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  ++nrules;
38525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  ++nritems;
38625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* Attach its location and actions to that of the DUMMY.  */
38725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  midrule->location = dummy_location;
3888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  code_props_rule_action_init (&midrule->action_props,
38925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune                               current_rule->action_props.code,
390e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard                               current_rule->action_props.location,
3918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune                               midrule, 0);
3928f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  code_props_none_init (&current_rule->action_props);
393e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
394e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  if (previous_rule_end)
395e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    previous_rule_end->next = midrule;
396e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  else
397e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard    grammar = midrule;
398e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard
399e3d4cbc7d25061441adafa47450a31571c87bf85Tom Stellard  /* End the dummy's rule.  */
40025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  midrule->next = symbol_list_sym_new (NULL, dummy_location);
40125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  midrule->next->next = current_rule;
40225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
4038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  previous_rule_end = midrule->next;
40425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
40525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* Insert the dummy nonterminal replacing the midrule action into
4068f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     the current rule.  Bind it to its dedicated rule.  */
4078f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  grammar_current_rule_symbol_append (dummy, dummy_location,
4088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune                                      action_name);
4098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  grammar_end->midrule = midrule;
4108f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  midrule->midrule_parent_rule = current_rule;
4118f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
4128f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
4138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4148f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/* Set the precedence symbol of the current rule to PRECSYM. */
4158f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4168f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
4178f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_current_rule_prec_set (symbol *precsym, location loc)
4188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune{
4198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* POSIX says that any identifier is a nonterminal if it does not
42025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     appear on the LHS of a grammar rule and is not defined by %token
42125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     or by one of the directives that assigns precedence to a token.  We
4228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     ignore this here because the only kind of identifier that POSIX
4238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     allows to follow a %prec is a token and because assuming it's a
4248f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     token now can produce more logical error messages.  Nevertheless,
4258f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     grammar_rule_check does obey what we believe is the real intent of
4268f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     POSIX here: that an error be reported for any identifier that
4278f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     appears after %prec but that is not defined separately as a
4288f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune     token.  */
4298f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  symbol_class_set (precsym, token_sym, loc, false);
4308f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (current_rule->ruleprec)
4318f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    complain_at (loc, _("only one %s allowed per rule"), "%prec");
4328f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  current_rule->ruleprec = precsym;
4338f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
4348f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4358f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/* Attach dynamic precedence DPREC to the current rule. */
4368f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
43725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeunevoid
43897daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramergrammar_current_rule_dprec_set (int dprec, location loc)
43997daabf318ff4751aca49bc1c334d2553b125671Benjamin Kramer{
4408f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (! glr_parser)
4418f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    warn_at (loc, _("%s affects only GLR parsers"), "%dprec");
4428f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (dprec <= 0)
4438f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    complain_at (loc, _("%s must be followed by positive number"), "%dprec");
4448f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  else if (current_rule->dprec != 0)
4458f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    complain_at (loc, _("only one %s allowed per rule"), "%dprec");
4468f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  current_rule->dprec = dprec;
4478f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
4488f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4498f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/* Attach a merge function NAME with argument type TYPE to current
4508f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune   rule. */
4518f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4528f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
4538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_current_rule_merge_set (uniqstr name, location loc)
45425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune{
4558f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (! glr_parser)
45625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    warn_at (loc, _("%s affects only GLR parsers"), "%merge");
45725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if (current_rule->merger != 0)
45825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    complain_at (loc, _("only one %s allowed per rule"), "%merge");
4598f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  current_rule->merger = get_merge_function (name);
4608f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  current_rule->merger_declaration_location = loc;
4618f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
4628f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4638f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune/* Attach SYM to the current rule.  If needed, move the previous
4648f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune   action as a mid-rule action.  */
4658f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4668f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
4678f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_current_rule_symbol_append (symbol *sym, location loc,
4688f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune				    named_ref *name)
4698f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune{
4708f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  symbol_list *p;
4718f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (current_rule->action_props.code)
4728f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    grammar_midrule_action ();
4738f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  p = grammar_symbol_append (sym, loc);
4748f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  if (name)
4758f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    assign_named_ref(p, name);
4768f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune}
4778f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
47825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune/* Attach an ACTION to the current rule.  */
47925c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
4808f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunevoid
4818f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunegrammar_current_rule_action_append (const char *action, location loc,
4828f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune				    named_ref *name)
48325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune{
48425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  if (current_rule->action_props.code)
48525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune    grammar_midrule_action ();
48625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune  /* After all symbol declarations have been parsed, packgram invokes
48725c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune     code_props_translate_code.  */
4888f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  code_props_rule_action_init (&current_rule->action_props, action, loc,
489c36a8d2b3d6e543de8d9f210ecd39a9a0641d826Vincent Lejeune                               current_rule, name);
49025c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune}
4918f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
49225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
4935e48a0e9ae2365a130dd1ec2e0b4beb337ab79e0Tom Stellard/*---------------------------------------------------------------.
49425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune| Convert the rules into the representation using RRHS, RLHS and |
49525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune| RITEM.                                                         |
49625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune`---------------------------------------------------------------*/
4978f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
4988f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunestatic void
4998f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeunepackgram (void)
5008f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune{
5018f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  unsigned int itemno = 0;
5028f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  rule_number ruleno = 0;
5038f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  symbol_list *p = grammar;
5048f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
5058f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  ritem = xnmalloc (nritems + 1, sizeof *ritem);
5068f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
5078f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  /* This sentinel is used by build_relations in gram.c.  */
5088f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  *ritem++ = 0;
5098f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
5108f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  rules = xnmalloc (nrules, sizeof *rules);
5118f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune
5128f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune  while (p)
5138f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune    {
5148f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      int rule_length = 0;
5158f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      symbol *ruleprec = p->ruleprec;
5168f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      record_merge_function_type (p->merger, p->content.sym->type_name,
5178f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune				  p->merger_declaration_location);
5188f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].user_number = ruleno;
5198f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].number = ruleno;
5208f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].lhs = p->content.sym;
5218f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].rhs = ritem + itemno;
5228f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].prec = NULL;
5238f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune      rules[ruleno].dprec = p->dprec;
52425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      rules[ruleno].merger = p->merger;
52525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      rules[ruleno].precsym = NULL;
52625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      rules[ruleno].location = p->location;
5273ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      rules[ruleno].useful = true;
5283ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      rules[ruleno].action = p->action_props.code;
5293ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      rules[ruleno].action_location = p->action_props.location;
5303ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5313ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      /* If the midrule's $$ is set or its $n is used, remove the `$' from the
5323ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	 symbol name so that it's a user-defined symbol so that the default
5333ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	 %destructor and %printer apply.  */
5343ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      if (p->midrule_parent_rule
5353ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune          && (p->action_props.is_value_used
5363ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	      || symbol_list_n_get (p->midrule_parent_rule,
5373ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune				    p->midrule_parent_rhs_index)
5383ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune                   ->action_props.is_value_used))
5393ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	p->content.sym->tag += 1;
5403ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5413ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      /* Don't check the generated rule 0.  It has no action, so some rhs
5423ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	 symbols may appear unused, but the parsing algorithm ensures that
5433ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	 %destructor's are invoked appropriately.  */
5443ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      if (p != grammar)
5453ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	grammar_rule_check (p);
5463ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5473ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      for (p = p->next; p && p->content.sym; p = p->next)
5483ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	{
5493ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	  ++rule_length;
5503ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5513ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	  /* Don't allow rule_length == INT_MAX, since that might
5523ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	     cause confusion with strtol if INT_MAX == LONG_MAX.  */
5538f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune	  if (rule_length == INT_MAX)
5548f9fbd67c3f803f7397843fdf4b2a7b7ca10189eVincent Lejeune	      fatal_at (rules[ruleno].location, _("rule is too long"));
5553ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5568e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune	  /* item_number = symbol_number.
5573ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	     But the former needs to contain more: negative rule numbers. */
55825c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	  ritem[itemno++] =
5593ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune            symbol_number_as_item_number (p->content.sym->number);
5603ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	  /* A rule gets by default the precedence and associativity
5613ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	     of its last token.  */
562a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper	  if (p->content.sym->class == token_sym && default_prec)
56325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	    rules[ruleno].prec = p->content.sym;
56425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	}
56525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune
56625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      /* If this rule has a %prec,
5678e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune         the specified symbol's precedence replaces the default.  */
5688e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune      if (ruleprec)
5698e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune	{
5708e37705a736f45c16ed82ca675f7e413aa3bf90eVincent Lejeune	  rules[ruleno].precsym = ruleprec;
57125c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	  rules[ruleno].prec = ruleprec;
57225c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune	}
57325c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      /* An item ends by the rule number (negated).  */
57425c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      ritem[itemno++] = rule_number_as_item_number (ruleno);
57525c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      aver (itemno < ITEM_NUMBER_MAX);
57625c209e9a262b623deca60fb6b886907e22c941bVincent Lejeune      ++ruleno;
57725f259cde28860ea76c2f5628010968945a28edbVincent Lejeune      aver (ruleno < RULE_NUMBER_MAX);
5783ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5793ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune      if (p)
5803ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune	p = p->next;
5813ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune    }
5823ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune
5833ab0ba3cd8a499ebcc7eda3d7585c5ab4e7f0711Vincent Lejeune  aver (itemno == nritems);
584f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
585f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (trace_flag & trace_sets)
586f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    ritem_print (stderr);
587f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
588f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
589f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/*------------------------------------------------------------------.
590f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| Read in the grammar specification and record it in the format     |
591f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| described in gram.h.  All actions are copied into ACTION_OBSTACK, |
592f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| in each case forming the body of a C function (YYACTION) which    |
593f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| contains a switch statement to decide which action to execute.    |
594f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard`------------------------------------------------------------------*/
595f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
596f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid
597f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardreader (void)
598f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard{
599f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Initialize the symbol table.  */
600f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  symbols_new ();
601f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
602f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Construct the accept symbol. */
603f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  accept = symbol_get ("$accept", empty_location);
604f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  accept->class = nterm_sym;
605f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  accept->number = nvars++;
606f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
607f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Construct the error token */
608f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  errtoken = symbol_get ("error", empty_location);
609f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  errtoken->class = token_sym;
610f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  errtoken->number = ntokens++;
611f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
612f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Construct a token that represents all undefined literal tokens.
613fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune     It is always token number 2.  */
614fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  undeftoken = symbol_get ("$undefined", empty_location);
615fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  undeftoken->class = token_sym;
616fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  undeftoken->number = ntokens++;
617fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune
618f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  gram_in = xfopen (grammar_file, "r");
619f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
620f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  gram__flex_debug = trace_flag & trace_scan;
621f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  gram_debug = trace_flag & trace_parse;
622f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  gram_scanner_initialize ();
623f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  gram_parse ();
624f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  prepare_percent_define_front_end_variables ();
625f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
626f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (! complaint_issued)
627f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    check_and_convert_grammar ();
628f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
629f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  xfclose (gram_in);
630f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
631f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
632f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic void
633f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardprepare_percent_define_front_end_variables (void)
634f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard{
635f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Set %define front-end variable defaults.  */
636fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  muscle_percent_define_default ("lr.keep-unreachable-states", "false");
637f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  {
638f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    char *lr_type;
639f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    /* IELR would be a better default, but LALR is historically the
640f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard       default.  */
641f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    muscle_percent_define_default ("lr.type", "lalr");
642f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    lr_type = muscle_percent_define_get ("lr.type");
643f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    if (0 != strcmp (lr_type, "canonical-lr"))
644f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      muscle_percent_define_default ("lr.default-reductions", "most");
645f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    else
646fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune      muscle_percent_define_default ("lr.default-reductions", "accepting");
647f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    free (lr_type);
648fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  }
649fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune
650fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  /* Check %define front-end variables.  */
651fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  {
652fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    static char const * const values[] = {
653fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune      "lr.type", "lalr", "ielr", "canonical-lr", NULL,
654f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      "lr.default-reductions", "most", "consistent", "accepting", NULL,
655fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune      NULL
656fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    };
657fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    muscle_percent_define_check_values (values);
658fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  }
659fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune}
660f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
661f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
662f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/*-------------------------------------------------------------.
663f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| Check the grammar that has just been read, and convert it to |
664f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard| internal form.					       |
665f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard`-------------------------------------------------------------*/
666f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
667f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardstatic void
668f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardcheck_and_convert_grammar (void)
669fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune{
670f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Grammar has been read.  Do some checking.  */
671f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (nrules == 0)
672f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    fatal (_("no rules in the input grammar"));
673f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
674f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* If the user did not define her ENDTOKEN, do it now. */
675f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (!endtoken)
676f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    {
677f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      endtoken = symbol_get ("$end", empty_location);
678f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      endtoken->class = token_sym;
679f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      endtoken->number = 0;
680f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      /* Value specified by POSIX.  */
681f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      endtoken->user_token_number = 0;
682f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    }
683f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
684f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Report any undefined symbols and consider them nonterminals.  */
685f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  symbols_check_defined ();
686f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
687f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Find the start symbol if no %start.  */
688f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  if (!start_flag)
689f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    {
690f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      symbol_list *node;
691f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      for (node = grammar;
692f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard           node != NULL && symbol_is_dummy (node->content.sym);
693f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard           node = node->next)
694f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard        {
695f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard          for (node = node->next;
696f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune               node != NULL && node->content.sym != NULL;
697f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune               node = node->next)
698f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune            ;
699f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune        }
700f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune      aver (node != NULL);
701f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune      grammar_start_symbol_set (node->content.sym,
702f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune                                node->content.sym->location);
703f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune    }
704f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune
705f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  /* Insert the initial rule, whose line is that of the first rule
706f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune     (not that of the start symbol):
707f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
708f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     accept: %start EOF.  */
709f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  {
710f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    symbol_list *p = symbol_list_sym_new (accept, empty_location);
711f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    p->location = grammar->location;
712f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    p->next = symbol_list_sym_new (startsymbol, empty_location);
713f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    p->next->next = symbol_list_sym_new (endtoken, empty_location);
714f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    p->next->next->next = symbol_list_sym_new (NULL, empty_location);
715f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    p->next->next->next->next = grammar;
716f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    nrules += 1;
717fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    nritems += 3;
718f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    grammar = p;
719f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
720f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
721f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  aver (nsyms <= SYMBOL_NUMBER_MAXIMUM && nsyms == ntokens + nvars);
722f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
723f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Assign the symbols their symbol numbers.  Write #defines for the
724f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     token symbols into FDEFINES if requested.  */
725fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune  symbols_pack ();
726f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard
727f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  /* Scan rule actions after invoking symbol_check_alias_consistency (in
728f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune     symbols_pack above) so that token types are set correctly before the rule
729f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune     action type checking.
730f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune
731f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune     Before invoking grammar_rule_check (in packgram below) on any rule, make
732f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune     sure all actions have already been scanned in order to set `used' flags.
733f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     Otherwise, checking that a midrule's $$ should be set will not always work
734f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     properly because the check must forward-reference the midrule's parent
735f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     rule.  For the same reason, all the `used' flags must be set before
736f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     checking whether to remove `$' from any midrule symbol name (also in
737f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard     packgram).  */
738f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  {
739f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard    symbol_list *sym;
740fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune    for (sym = grammar; sym; sym = sym->next)
741f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard      code_props_translate_code (&sym->action_props);
742f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard  }
743fd49dac48fee6da580157515dec55ed2f2d8f2b3Vincent Lejeune
744f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  /* Convert the grammar into the format described in gram.h.  */
745f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  packgram ();
746f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune
747f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  /* The grammar as a symbol_list is no longer needed. */
748f2cfef8172fd2eceb036b8caff50623a189ba2ffVincent Lejeune  symbol_list_free (grammar);
749f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}
750f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard