reader.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. /* Input parser for Bison
  2. Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000-2003, 2005-2007,
  3. 2009-2013 Free Software Foundation, Inc.
  4. This file is part of Bison, the GNU Compiler Compiler.
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include <config.h>
  16. #include "system.h"
  17. #include <quote.h>
  18. #include "complain.h"
  19. #include "conflicts.h"
  20. #include "files.h"
  21. #include "getargs.h"
  22. #include "gram.h"
  23. #include "muscle-tab.h"
  24. #include "reader.h"
  25. #include "symlist.h"
  26. #include "symtab.h"
  27. #include "scan-gram.h"
  28. #include "scan-code.h"
  29. static void prepare_percent_define_front_end_variables (void);
  30. static void check_and_convert_grammar (void);
  31. static symbol_list *grammar = NULL;
  32. static bool start_flag = false;
  33. merger_list *merge_functions;
  34. /* Was %union seen? */
  35. bool union_seen = false;
  36. /* Was a tag seen? */
  37. bool tag_seen = false;
  38. /* Should rules have a default precedence? */
  39. bool default_prec = true;
  40. /*-----------------------.
  41. | Set the start symbol. |
  42. `-----------------------*/
  43. void
  44. grammar_start_symbol_set (symbol *sym, location loc)
  45. {
  46. if (start_flag)
  47. complain (&loc, complaint, _("multiple %s declarations"), "%start");
  48. else
  49. {
  50. start_flag = true;
  51. startsymbol = sym;
  52. startsymbol_location = loc;
  53. }
  54. }
  55. /*------------------------------------------------------------------------.
  56. | Return the merger index for a merging function named NAME. Records the |
  57. | function, if new, in MERGER_LIST. |
  58. `------------------------------------------------------------------------*/
  59. static int
  60. get_merge_function (uniqstr name)
  61. {
  62. merger_list *syms;
  63. merger_list head;
  64. int n;
  65. if (! glr_parser)
  66. return 0;
  67. head.next = merge_functions;
  68. for (syms = &head, n = 1; syms->next; syms = syms->next, n += 1)
  69. if (UNIQSTR_EQ (name, syms->next->name))
  70. break;
  71. if (syms->next == NULL)
  72. {
  73. syms->next = xmalloc (sizeof syms->next[0]);
  74. syms->next->name = uniqstr_new (name);
  75. /* After all symbol type declarations have been parsed, packgram invokes
  76. record_merge_function_type to set the type. */
  77. syms->next->type = NULL;
  78. syms->next->next = NULL;
  79. merge_functions = head.next;
  80. }
  81. return n;
  82. }
  83. /*-------------------------------------------------------------------------.
  84. | For the existing merging function with index MERGER, record the result |
  85. | type as TYPE as required by the lhs of the rule whose %merge declaration |
  86. | is at DECLARATION_LOC. |
  87. `-------------------------------------------------------------------------*/
  88. static void
  89. record_merge_function_type (int merger, uniqstr type, location declaration_loc)
  90. {
  91. int merger_find;
  92. merger_list *merge_function;
  93. if (merger <= 0)
  94. return;
  95. if (type == NULL)
  96. type = uniqstr_new ("");
  97. merger_find = 1;
  98. for (merge_function = merge_functions;
  99. merge_function != NULL && merger_find != merger;
  100. merge_function = merge_function->next)
  101. merger_find += 1;
  102. aver (merge_function != NULL && merger_find == merger);
  103. if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
  104. {
  105. unsigned indent = 0;
  106. complain_indent (&declaration_loc, complaint, &indent,
  107. _("result type clash on merge function %s: "
  108. "<%s> != <%s>"),
  109. quote (merge_function->name), type,
  110. merge_function->type);
  111. indent += SUB_INDENT;
  112. complain_indent (&merge_function->type_declaration_location, complaint,
  113. &indent,
  114. _("previous declaration"));
  115. }
  116. merge_function->type = uniqstr_new (type);
  117. merge_function->type_declaration_location = declaration_loc;
  118. }
  119. /*--------------------------------------.
  120. | Free all merge-function definitions. |
  121. `--------------------------------------*/
  122. void
  123. free_merger_functions (void)
  124. {
  125. merger_list *L0 = merge_functions;
  126. while (L0)
  127. {
  128. merger_list *L1 = L0->next;
  129. free (L0);
  130. L0 = L1;
  131. }
  132. }
  133. /*-------------------------------------------------------------------.
  134. | Parse the input grammar into a one symbol_list structure. Each |
  135. | rule is represented by a sequence of symbols: the left hand side |
  136. | followed by the contents of the right hand side, followed by a |
  137. | null pointer instead of a symbol to terminate the rule. The next |
  138. | symbol is the lhs of the following rule. |
  139. | |
  140. | All actions are copied out, labelled by the rule number they apply |
  141. | to. |
  142. `-------------------------------------------------------------------*/
  143. /* The (currently) last symbol of GRAMMAR. */
  144. static symbol_list *grammar_end = NULL;
  145. /* Append SYM to the grammar. */
  146. static symbol_list *
  147. grammar_symbol_append (symbol *sym, location loc)
  148. {
  149. symbol_list *p = symbol_list_sym_new (sym, loc);
  150. if (grammar_end)
  151. grammar_end->next = p;
  152. else
  153. grammar = p;
  154. grammar_end = p;
  155. /* A null SYM stands for an end of rule; it is not an actual
  156. part of it. */
  157. if (sym)
  158. ++nritems;
  159. return p;
  160. }
  161. static void
  162. assign_named_ref (symbol_list *p, named_ref *name)
  163. {
  164. symbol *sym = p->content.sym;
  165. if (name->id == sym->tag)
  166. {
  167. complain (&name->loc, Wother,
  168. _("duplicated symbol name for %s ignored"),
  169. quote (sym->tag));
  170. named_ref_free (name);
  171. }
  172. else
  173. p->named_ref = name;
  174. }
  175. /* The rule currently being defined, and the previous rule.
  176. CURRENT_RULE points to the first LHS of the current rule, while
  177. PREVIOUS_RULE_END points to the *end* of the previous rule (NULL). */
  178. static symbol_list *current_rule = NULL;
  179. static symbol_list *previous_rule_end = NULL;
  180. /*----------------------------------------------.
  181. | Create a new rule for LHS in to the GRAMMAR. |
  182. `----------------------------------------------*/
  183. void
  184. grammar_current_rule_begin (symbol *lhs, location loc,
  185. named_ref *lhs_name)
  186. {
  187. symbol_list* p;
  188. /* Start a new rule and record its lhs. */
  189. ++nrules;
  190. previous_rule_end = grammar_end;
  191. p = grammar_symbol_append (lhs, loc);
  192. if (lhs_name)
  193. assign_named_ref (p, named_ref_copy (lhs_name));
  194. current_rule = grammar_end;
  195. /* Mark the rule's lhs as a nonterminal if not already so. */
  196. if (lhs->class == unknown_sym)
  197. {
  198. lhs->class = nterm_sym;
  199. lhs->number = nvars;
  200. ++nvars;
  201. }
  202. else if (lhs->class == token_sym)
  203. complain (&loc, complaint, _("rule given for %s, which is a token"),
  204. lhs->tag);
  205. }
  206. /*----------------------------------------------------------------------.
  207. | A symbol should be used if either: |
  208. | 1. It has a destructor. |
  209. | 2. The symbol is a mid-rule symbol (i.e., the generated LHS |
  210. | replacing a mid-rule action) that was assigned to or used, as in |
  211. | "exp: { $$ = 1; } { $$ = $1; }". |
  212. `----------------------------------------------------------------------*/
  213. static bool
  214. symbol_should_be_used (symbol_list const *s, bool *midrule_warning)
  215. {
  216. if (symbol_code_props_get (s->content.sym, destructor)->code)
  217. return true;
  218. if ((s->midrule && s->midrule->action_props.is_value_used)
  219. || (s->midrule_parent_rule
  220. && (symbol_list_n_get (s->midrule_parent_rule,
  221. s->midrule_parent_rhs_index)
  222. ->action_props.is_value_used)))
  223. {
  224. *midrule_warning = true;
  225. return true;
  226. }
  227. return false;
  228. }
  229. /*----------------------------------------------------------------.
  230. | Check that the rule R is properly defined. For instance, there |
  231. | should be no type clash on the default action. |
  232. `----------------------------------------------------------------*/
  233. static void
  234. grammar_rule_check (const symbol_list *r)
  235. {
  236. /* Type check.
  237. If there is an action, then there is nothing we can do: the user
  238. is allowed to shoot herself in the foot.
  239. Don't worry about the default action if $$ is untyped, since $$'s
  240. value can't be used. */
  241. if (!r->action_props.code && r->content.sym->type_name)
  242. {
  243. symbol *first_rhs = r->next->content.sym;
  244. /* If $$ is being set in default way, report if any type mismatch. */
  245. if (first_rhs)
  246. {
  247. char const *lhs_type = r->content.sym->type_name;
  248. const char *rhs_type =
  249. first_rhs->type_name ? first_rhs->type_name : "";
  250. if (!UNIQSTR_EQ (lhs_type, rhs_type))
  251. complain (&r->location, Wother,
  252. _("type clash on default action: <%s> != <%s>"),
  253. lhs_type, rhs_type);
  254. }
  255. /* Warn if there is no default for $$ but we need one. */
  256. else
  257. complain (&r->location, Wother,
  258. _("empty rule for typed nonterminal, and no action"));
  259. }
  260. /* Check that symbol values that should be used are in fact used. */
  261. {
  262. symbol_list const *l = r;
  263. int n = 0;
  264. for (; l && l->content.sym; l = l->next, ++n)
  265. {
  266. bool midrule_warning = false;
  267. if (!l->action_props.is_value_used
  268. && symbol_should_be_used (l, &midrule_warning)
  269. /* The default action, $$ = $1, 'uses' both. */
  270. && (r->action_props.code || (n != 0 && n != 1)))
  271. {
  272. warnings warn_flag = midrule_warning ? Wmidrule_values : Wother;
  273. if (n)
  274. complain (&l->location, warn_flag, _("unused value: $%d"), n);
  275. else
  276. complain (&l->location, warn_flag, _("unset value: $$"));
  277. }
  278. }
  279. }
  280. /* Check that %empty => empty rule. */
  281. if (r->percent_empty_loc.start.file
  282. && r->next && r->next->content.sym)
  283. complain (&r->percent_empty_loc, complaint,
  284. _("%%empty on non-empty rule"));
  285. /* Check that empty rule => %empty. */
  286. if (!(r->next && r->next->content.sym)
  287. && !r->midrule_parent_rule
  288. && !r->percent_empty_loc.start.file)
  289. complain (&r->location, Wempty_rule, _("empty rule without %%empty"));
  290. /* See comments in grammar_current_rule_prec_set for how POSIX
  291. mandates this complaint. It's only for identifiers, so skip
  292. it for char literals and strings, which are always tokens. */
  293. if (r->ruleprec
  294. && r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
  295. && r->ruleprec->status != declared && !r->ruleprec->prec)
  296. complain (&r->location, Wother,
  297. _("token for %%prec is not defined: %s"), r->ruleprec->tag);
  298. }
  299. /*-------------------------------------.
  300. | End the currently being grown rule. |
  301. `-------------------------------------*/
  302. void
  303. grammar_current_rule_end (location loc)
  304. {
  305. /* Put an empty link in the list to mark the end of this rule */
  306. grammar_symbol_append (NULL, grammar_end->location);
  307. current_rule->location = loc;
  308. }
  309. /*-------------------------------------------------------------------.
  310. | The previous action turns out the be a mid-rule action. Attach it |
  311. | to the current rule, i.e., create a dummy symbol, attach it this |
  312. | mid-rule action, and append this dummy nonterminal to the current |
  313. | rule. |
  314. `-------------------------------------------------------------------*/
  315. void
  316. grammar_midrule_action (void)
  317. {
  318. /* Since the action was written out with this rule's number, we must
  319. give the new rule this number by inserting the new rule before
  320. it. */
  321. /* Make a DUMMY nonterminal, whose location is that of the midrule
  322. action. Create the MIDRULE. */
  323. location dummy_location = current_rule->action_props.location;
  324. symbol *dummy = dummy_symbol_get (dummy_location);
  325. symbol_list *midrule = symbol_list_sym_new (dummy, dummy_location);
  326. /* Remember named_ref of previous action. */
  327. named_ref *action_name = current_rule->action_props.named_ref;
  328. /* Make a new rule, whose body is empty, before the current one, so
  329. that the action just read can belong to it. */
  330. ++nrules;
  331. ++nritems;
  332. /* Attach its location and actions to that of the DUMMY. */
  333. midrule->location = dummy_location;
  334. code_props_rule_action_init (&midrule->action_props,
  335. current_rule->action_props.code,
  336. current_rule->action_props.location,
  337. midrule, 0,
  338. current_rule->action_props.is_predicate);
  339. code_props_none_init (&current_rule->action_props);
  340. if (previous_rule_end)
  341. previous_rule_end->next = midrule;
  342. else
  343. grammar = midrule;
  344. /* End the dummy's rule. */
  345. midrule->next = symbol_list_sym_new (NULL, dummy_location);
  346. midrule->next->next = current_rule;
  347. previous_rule_end = midrule->next;
  348. /* Insert the dummy nonterminal replacing the midrule action into
  349. the current rule. Bind it to its dedicated rule. */
  350. grammar_current_rule_symbol_append (dummy, dummy_location,
  351. action_name);
  352. grammar_end->midrule = midrule;
  353. midrule->midrule_parent_rule = current_rule;
  354. midrule->midrule_parent_rhs_index = symbol_list_length (current_rule->next);
  355. }
  356. /* Set the precedence symbol of the current rule to PRECSYM. */
  357. void
  358. grammar_current_rule_prec_set (symbol *precsym, location loc)
  359. {
  360. /* POSIX says that any identifier is a nonterminal if it does not
  361. appear on the LHS of a grammar rule and is not defined by %token
  362. or by one of the directives that assigns precedence to a token. We
  363. ignore this here because the only kind of identifier that POSIX
  364. allows to follow a %prec is a token and because assuming it's a
  365. token now can produce more logical error messages. Nevertheless,
  366. grammar_rule_check does obey what we believe is the real intent of
  367. POSIX here: that an error be reported for any identifier that
  368. appears after %prec but that is not defined separately as a
  369. token. */
  370. symbol_class_set (precsym, token_sym, loc, false);
  371. if (current_rule->ruleprec)
  372. duplicate_directive ("%prec",
  373. current_rule->ruleprec->location, loc);
  374. else
  375. current_rule->ruleprec = precsym;
  376. }
  377. /* Set %empty for the current rule. */
  378. void
  379. grammar_current_rule_empty_set (location loc)
  380. {
  381. /* If %empty is used and -Wno-empty-rule is not, then enable
  382. -Wempty-rule. */
  383. if (warning_is_unset (Wempty_rule))
  384. warning_argmatch ("empty-rule", 0, 0);
  385. if (current_rule->percent_empty_loc.start.file)
  386. duplicate_directive ("%empty",
  387. current_rule->percent_empty_loc, loc);
  388. else
  389. current_rule->percent_empty_loc = loc;
  390. }
  391. /* Attach dynamic precedence DPREC to the current rule. */
  392. void
  393. grammar_current_rule_dprec_set (int dprec, location loc)
  394. {
  395. if (! glr_parser)
  396. complain (&loc, Wother, _("%s affects only GLR parsers"),
  397. "%dprec");
  398. if (dprec <= 0)
  399. complain (&loc, complaint, _("%s must be followed by positive number"),
  400. "%dprec");
  401. else if (current_rule->dprec != 0)
  402. duplicate_directive ("%dprec",
  403. current_rule->dprec_location, loc);
  404. else
  405. {
  406. current_rule->dprec = dprec;
  407. current_rule->dprec_location = loc;
  408. }
  409. }
  410. /* Attach a merge function NAME with argument type TYPE to current
  411. rule. */
  412. void
  413. grammar_current_rule_merge_set (uniqstr name, location loc)
  414. {
  415. if (! glr_parser)
  416. complain (&loc, Wother, _("%s affects only GLR parsers"),
  417. "%merge");
  418. if (current_rule->merger != 0)
  419. duplicate_directive ("%merge",
  420. current_rule->merger_declaration_location, loc);
  421. else
  422. {
  423. current_rule->merger = get_merge_function (name);
  424. current_rule->merger_declaration_location = loc;
  425. }
  426. }
  427. /* Attach SYM to the current rule. If needed, move the previous
  428. action as a mid-rule action. */
  429. void
  430. grammar_current_rule_symbol_append (symbol *sym, location loc,
  431. named_ref *name)
  432. {
  433. symbol_list *p;
  434. if (current_rule->action_props.code)
  435. grammar_midrule_action ();
  436. p = grammar_symbol_append (sym, loc);
  437. if (name)
  438. assign_named_ref (p, name);
  439. if (sym->status == undeclared || sym->status == used)
  440. sym->status = needed;
  441. }
  442. /* Attach an ACTION to the current rule. */
  443. void
  444. grammar_current_rule_action_append (const char *action, location loc,
  445. named_ref *name, bool is_predicate)
  446. {
  447. if (current_rule->action_props.code)
  448. grammar_midrule_action ();
  449. /* After all symbol declarations have been parsed, packgram invokes
  450. code_props_translate_code. */
  451. code_props_rule_action_init (&current_rule->action_props, action, loc,
  452. current_rule, name, is_predicate);
  453. }
  454. /*---------------------------------------------------------------.
  455. | Convert the rules into the representation using RRHS, RLHS and |
  456. | RITEM. |
  457. `---------------------------------------------------------------*/
  458. static void
  459. packgram (void)
  460. {
  461. unsigned int itemno = 0;
  462. rule_number ruleno = 0;
  463. symbol_list *p;
  464. ritem = xnmalloc (nritems + 1, sizeof *ritem);
  465. /* This sentinel is used by build_relations in gram.c. */
  466. *ritem++ = 0;
  467. rules = xnmalloc (nrules, sizeof *rules);
  468. for (p = grammar; p; p = p->next)
  469. {
  470. symbol *ruleprec = p->ruleprec;
  471. record_merge_function_type (p->merger, p->content.sym->type_name,
  472. p->merger_declaration_location);
  473. rules[ruleno].user_number = ruleno;
  474. rules[ruleno].number = ruleno;
  475. rules[ruleno].lhs = p->content.sym;
  476. rules[ruleno].rhs = ritem + itemno;
  477. rules[ruleno].prec = NULL;
  478. rules[ruleno].dprec = p->dprec;
  479. rules[ruleno].merger = p->merger;
  480. rules[ruleno].precsym = NULL;
  481. rules[ruleno].location = p->location;
  482. rules[ruleno].useful = true;
  483. rules[ruleno].action = p->action_props.code;
  484. rules[ruleno].action_location = p->action_props.location;
  485. rules[ruleno].is_predicate = p->action_props.is_predicate;
  486. /* If the midrule's $$ is set or its $n is used, remove the '$' from the
  487. symbol name so that it's a user-defined symbol so that the default
  488. %destructor and %printer apply. */
  489. if (p->midrule_parent_rule
  490. && (p->action_props.is_value_used
  491. || (symbol_list_n_get (p->midrule_parent_rule,
  492. p->midrule_parent_rhs_index)
  493. ->action_props.is_value_used)))
  494. p->content.sym->tag += 1;
  495. /* Don't check the generated rule 0. It has no action, so some rhs
  496. symbols may appear unused, but the parsing algorithm ensures that
  497. %destructor's are invoked appropriately. */
  498. if (p != grammar)
  499. grammar_rule_check (p);
  500. {
  501. size_t rule_length = 0;
  502. for (p = p->next; p->content.sym; p = p->next)
  503. {
  504. ++rule_length;
  505. /* Don't allow rule_length == INT_MAX, since that might
  506. cause confusion with strtol if INT_MAX == LONG_MAX. */
  507. if (rule_length == INT_MAX)
  508. complain (&rules[ruleno].location, fatal, _("rule is too long"));
  509. /* item_number = symbol_number.
  510. But the former needs to contain more: negative rule numbers. */
  511. ritem[itemno++] =
  512. symbol_number_as_item_number (p->content.sym->number);
  513. /* A rule gets by default the precedence and associativity
  514. of its last token. */
  515. if (p->content.sym->class == token_sym && default_prec)
  516. rules[ruleno].prec = p->content.sym;
  517. }
  518. }
  519. /* If this rule has a %prec,
  520. the specified symbol's precedence replaces the default. */
  521. if (ruleprec)
  522. {
  523. rules[ruleno].precsym = ruleprec;
  524. rules[ruleno].prec = ruleprec;
  525. }
  526. /* An item ends by the rule number (negated). */
  527. ritem[itemno++] = rule_number_as_item_number (ruleno);
  528. aver (itemno < ITEM_NUMBER_MAX);
  529. ++ruleno;
  530. aver (ruleno < RULE_NUMBER_MAX);
  531. }
  532. aver (itemno == nritems);
  533. if (trace_flag & trace_sets)
  534. ritem_print (stderr);
  535. }
  536. /*------------------------------------------------------------------.
  537. | Read in the grammar specification and record it in the format |
  538. | described in gram.h. All actions are copied into ACTION_OBSTACK, |
  539. | in each case forming the body of a C function (YYACTION) which |
  540. | contains a switch statement to decide which action to execute. |
  541. `------------------------------------------------------------------*/
  542. void
  543. reader (void)
  544. {
  545. /* Initialize the symbol table. */
  546. symbols_new ();
  547. /* Construct the accept symbol. */
  548. accept = symbol_get ("$accept", empty_location);
  549. accept->class = nterm_sym;
  550. accept->number = nvars++;
  551. /* Construct the error token */
  552. errtoken = symbol_get ("error", empty_location);
  553. errtoken->class = token_sym;
  554. errtoken->number = ntokens++;
  555. /* Construct a token that represents all undefined literal tokens.
  556. It is always token number 2. */
  557. undeftoken = symbol_get ("$undefined", empty_location);
  558. undeftoken->class = token_sym;
  559. undeftoken->number = ntokens++;
  560. gram_in = xfopen (grammar_file, "r");
  561. gram__flex_debug = trace_flag & trace_scan;
  562. gram_debug = trace_flag & trace_parse;
  563. gram_scanner_initialize ();
  564. gram_parse ();
  565. prepare_percent_define_front_end_variables ();
  566. if (complaint_status < status_complaint)
  567. check_and_convert_grammar ();
  568. xfclose (gram_in);
  569. }
  570. static void
  571. prepare_percent_define_front_end_variables (void)
  572. {
  573. /* Set %define front-end variable defaults. */
  574. muscle_percent_define_default ("lr.keep-unreachable-state", "false");
  575. {
  576. char *lr_type;
  577. /* IELR would be a better default, but LALR is historically the
  578. default. */
  579. muscle_percent_define_default ("lr.type", "lalr");
  580. lr_type = muscle_percent_define_get ("lr.type");
  581. if (STRNEQ (lr_type, "canonical-lr"))
  582. muscle_percent_define_default ("lr.default-reduction", "most");
  583. else
  584. muscle_percent_define_default ("lr.default-reduction", "accepting");
  585. free (lr_type);
  586. }
  587. /* Check %define front-end variables. */
  588. {
  589. static char const * const values[] = {
  590. "lr.type", "lalr", "ielr", "canonical-lr", NULL,
  591. "lr.default-reduction", "most", "consistent", "accepting", NULL,
  592. NULL
  593. };
  594. muscle_percent_define_check_values (values);
  595. }
  596. }
  597. /*-------------------------------------------------------------.
  598. | Check the grammar that has just been read, and convert it to |
  599. | internal form. |
  600. `-------------------------------------------------------------*/
  601. static void
  602. check_and_convert_grammar (void)
  603. {
  604. /* Grammar has been read. Do some checking. */
  605. if (nrules == 0)
  606. complain (NULL, fatal, _("no rules in the input grammar"));
  607. /* If the user did not define her ENDTOKEN, do it now. */
  608. if (!endtoken)
  609. {
  610. endtoken = symbol_get ("$end", empty_location);
  611. endtoken->class = token_sym;
  612. endtoken->number = 0;
  613. /* Value specified by POSIX. */
  614. endtoken->user_token_number = 0;
  615. }
  616. /* Report any undefined symbols and consider them nonterminals. */
  617. symbols_check_defined ();
  618. /* Find the start symbol if no %start. */
  619. if (!start_flag)
  620. {
  621. symbol_list *node;
  622. for (node = grammar;
  623. node != NULL && symbol_is_dummy (node->content.sym);
  624. node = node->next)
  625. {
  626. for (node = node->next;
  627. node != NULL && node->content.sym != NULL;
  628. node = node->next)
  629. ;
  630. }
  631. aver (node != NULL);
  632. grammar_start_symbol_set (node->content.sym,
  633. node->content.sym->location);
  634. }
  635. /* Insert the initial rule, whose line is that of the first rule
  636. (not that of the start symbol):
  637. $accept: %start $end. */
  638. {
  639. symbol_list *p = symbol_list_sym_new (accept, empty_location);
  640. p->location = grammar->location;
  641. p->next = symbol_list_sym_new (startsymbol, empty_location);
  642. p->next->next = symbol_list_sym_new (endtoken, empty_location);
  643. p->next->next->next = symbol_list_sym_new (NULL, empty_location);
  644. p->next->next->next->next = grammar;
  645. nrules += 1;
  646. nritems += 3;
  647. grammar = p;
  648. }
  649. aver (nsyms <= SYMBOL_NUMBER_MAXIMUM);
  650. aver (nsyms == ntokens + nvars);
  651. /* Assign the symbols their symbol numbers. Write #defines for the
  652. token symbols into FDEFINES if requested. */
  653. symbols_pack ();
  654. /* Scan rule actions after invoking symbol_check_alias_consistency (in
  655. symbols_pack above) so that token types are set correctly before the rule
  656. action type checking.
  657. Before invoking grammar_rule_check (in packgram below) on any rule, make
  658. sure all actions have already been scanned in order to set 'used' flags.
  659. Otherwise, checking that a midrule's $$ should be set will not always work
  660. properly because the check must forward-reference the midrule's parent
  661. rule. For the same reason, all the 'used' flags must be set before
  662. checking whether to remove '$' from any midrule symbol name (also in
  663. packgram). */
  664. {
  665. symbol_list *sym;
  666. for (sym = grammar; sym; sym = sym->next)
  667. code_props_translate_code (&sym->action_props);
  668. }
  669. /* Convert the grammar into the format described in gram.h. */
  670. packgram ();
  671. /* The grammar as a symbol_list is no longer needed. */
  672. symbol_list_free (grammar);
  673. }