1 /* Allocate input grammar variables for Bison.
3 Copyright (C) 1984, 1986, 1989, 2001-2003, 2005-2015, 2018-2022 Free
4 Software Foundation, Inc.
6 This file is part of Bison, the GNU Compiler Compiler.
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>. */
28 #include "print-xml.h"
33 /* Comments for these variables are in gram.h. */
35 item_number
*ritem
= NULL
;
39 rule_number nrules
= 0;
41 symbol
**symbols
= NULL
;
46 symbol_number
*token_translations
= NULL
;
50 int required_version
= 0;
53 item_print (item_number
*item
, rule
const *previous_rule
, FILE *out
)
55 rule
const *r
= item_rule (item
);
56 rule_lhs_print (r
, previous_rule
? previous_rule
->lhs
: NULL
, out
);
61 for (item_number
*sp
= r
->rhs
; sp
< item
; sp
++)
62 fprintf (out
, " %s", symbols
[*sp
]->tag
);
63 fprintf (out
, " %s", dot
);
64 for (item_number
*sp
= item
; 0 <= *sp
; ++sp
)
65 fprintf (out
, " %s", symbols
[*sp
]->tag
);
68 fprintf (out
, " %s %s", empty
, dot
);
73 rule_useful_in_grammar_p (rule
const *r
)
75 return r
->number
< nrules
;
79 rule_useless_in_grammar_p (rule
const *r
)
81 return !rule_useful_in_grammar_p (r
);
85 rule_useless_in_parser_p (rule
const *r
)
87 return !r
->useful
&& rule_useful_in_grammar_p (r
);
91 rule_useless_chain_p (rule
const *r
)
93 return rule_rhs_length (r
) == 1 && !r
->action
;
97 rule_lhs_print (rule
const *r
, sym_content
const *previous_lhs
, FILE *out
)
99 fprintf (out
, " %3d ", r
->number
);
100 if (previous_lhs
!= r
->lhs
)
101 fprintf (out
, "%s:", r
->lhs
->symbol
->tag
);
103 fprintf (out
, "%*s|", (int) strlen (previous_lhs
->symbol
->tag
), "");
107 rule_lhs_print_xml (rule
const *r
, FILE *out
, int level
)
109 xml_printf (out
, level
, "<lhs>%s</lhs>", r
->lhs
->symbol
->tag
);
113 rule_rhs_length (rule
const *r
)
116 for (item_number
*rhsp
= r
->rhs
; 0 <= *rhsp
; ++rhsp
)
122 rule_rhs_print (rule
const *r
, FILE *out
)
125 for (item_number
*rhsp
= r
->rhs
; 0 <= *rhsp
; ++rhsp
)
126 fprintf (out
, " %s", symbols
[*rhsp
]->tag
);
128 fprintf (out
, " %s", empty
);
132 rule_rhs_print_xml (rule
const *r
, FILE *out
, int level
)
136 xml_puts (out
, level
, "<rhs>");
137 for (item_number
*rhsp
= r
->rhs
; 0 <= *rhsp
; ++rhsp
)
138 xml_printf (out
, level
+ 1, "<symbol>%s</symbol>",
139 xml_escape (symbols
[*rhsp
]->tag
));
140 xml_puts (out
, level
, "</rhs>");
144 xml_puts (out
, level
, "<rhs>");
145 xml_puts (out
, level
+ 1, "<empty/>");
146 xml_puts (out
, level
, "</rhs>");
151 rule_print (rule
const *r
, rule
const *prev_rule
, FILE *out
)
153 rule_lhs_print (r
, prev_rule
? prev_rule
->lhs
: NULL
, out
);
154 rule_rhs_print (r
, out
);
158 ritem_print (FILE *out
)
160 fputs ("RITEM\n", out
);
162 for (int i
= 0; i
< nritems
; ++i
)
166 fprintf (out
, " %d: ", i
);
170 fprintf (out
, " %s", symbols
[ritem
[i
]]->tag
);
173 fprintf (out
, " (rule %d)\n", item_number_as_rule_number (ritem
[i
]));
181 ritem_longest_rhs (void)
184 for (rule_number r
= 0; r
< nrules
; ++r
)
186 size_t length
= rule_rhs_length (&rules
[r
]);
195 grammar_rules_partial_print (FILE *out
, const char *title
,
199 rule
*previous_rule
= NULL
;
201 /* rule # : LHS -> RHS */
202 for (rule_number r
= 0; r
< nrules
+ nuseless_productions
; r
++)
204 if (filter
&& !filter (&rules
[r
]))
207 fprintf (out
, "%s\n\n", title
);
208 else if (previous_rule
&& previous_rule
->lhs
!= rules
[r
].lhs
)
211 rule_print (&rules
[r
], previous_rule
, out
);
213 previous_rule
= &rules
[r
];
220 grammar_rules_print (FILE *out
)
222 grammar_rules_partial_print (out
, _("Grammar"), rule_useful_in_grammar_p
);
226 grammar_rules_print_xml (FILE *out
, int level
)
230 for (rule_number r
= 0; r
< nrules
+ nuseless_productions
; r
++)
233 xml_puts (out
, level
+ 1, "<rules>");
236 char const *usefulness
237 = rule_useless_in_grammar_p (&rules
[r
]) ? "useless-in-grammar"
238 : rule_useless_in_parser_p (&rules
[r
]) ? "useless-in-parser"
240 xml_indent (out
, level
+ 2);
241 fprintf (out
, "<rule number=\"%d\" usefulness=\"%s\"",
242 rules
[r
].number
, usefulness
);
243 if (rules
[r
].precsym
)
244 fprintf (out
, " percent_prec=\"%s\"",
245 xml_escape (rules
[r
].precsym
->symbol
->tag
));
248 rule_lhs_print_xml (&rules
[r
], out
, level
+ 3);
249 rule_rhs_print_xml (&rules
[r
], out
, level
+ 3);
250 xml_puts (out
, level
+ 2, "</rule>");
253 xml_puts (out
, level
+ 1, "</rules>");
255 xml_puts (out
, level
+ 1, "<rules/>");
259 section (FILE *out
, const char *s
)
261 fprintf (out
, "%s\n", s
);
262 for (int i
= strlen (s
); 0 < i
; --i
)
269 grammar_dump (FILE *out
, const char *title
)
271 fprintf (out
, "%s\n\n", title
);
273 "ntokens = %d, nnterms = %d, nsyms = %d, nrules = %d, nritems = %d\n\n",
274 ntokens
, nnterms
, nsyms
, nrules
, nritems
);
276 section (out
, "Tokens");
278 fprintf (out
, "Value Sprec Sassoc Tag\n");
280 for (symbol_number i
= 0; i
< ntokens
; i
++)
281 fprintf (out
, "%5d %5d %5d %s\n",
283 symbols
[i
]->content
->prec
, symbols
[i
]->content
->assoc
,
285 fprintf (out
, "\n\n");
288 section (out
, "Nonterminals");
290 fprintf (out
, "Value Tag\n");
292 for (symbol_number i
= ntokens
; i
< nsyms
; i
++)
293 fprintf (out
, "%5d %s\n",
295 fprintf (out
, "\n\n");
298 section (out
, "Rules");
301 "Num (Prec, Assoc, Useful, UselessChain) Lhs"
302 " -> (Ritem Range) Rhs\n");
303 for (rule_number i
= 0; i
< nrules
+ nuseless_productions
; ++i
)
305 rule
const *rule_i
= &rules
[i
];
306 int const rhs_itemno
= rule_i
->rhs
- ritem
;
307 int length
= rule_rhs_length (rule_i
);
308 aver (item_number_as_rule_number (rule_i
->rhs
[length
]) == i
);
309 fprintf (out
, "%3d (%2d, %2d, %2s, %2s) %2d -> (%2u-%2u)",
311 rule_i
->prec
? rule_i
->prec
->prec
: 0,
312 rule_i
->prec
? rule_i
->prec
->assoc
: 0,
313 rule_i
->useful
? "t" : "f",
314 rule_useless_chain_p (rule_i
) ? "t" : "f",
316 rhs_itemno
, rhs_itemno
+ length
- 1);
317 /* Dumped the RHS. */
318 for (item_number
*rhsp
= rule_i
->rhs
; 0 <= *rhsp
; ++rhsp
)
319 fprintf (out
, " %3d", *rhsp
);
323 fprintf (out
, "\n\n");
325 section (out
, "Rules interpreted");
326 for (rule_number r
= 0; r
< nrules
+ nuseless_productions
; ++r
)
328 fprintf (out
, "%-5d %s:", r
, rules
[r
].lhs
->symbol
->tag
);
329 rule_rhs_print (&rules
[r
], out
);
332 fprintf (out
, "\n\n");
336 grammar_rules_useless_report (const char *message
)
338 for (rule_number r
= 0; r
< nrules
; ++r
)
339 /* Don't complain about rules whose LHS is useless, we already
340 complained about it. */
341 if (!reduce_nonterminal_useless_in_grammar (rules
[r
].lhs
)
343 complain (&rules
[r
].location
, Wother
, "%s", message
);
352 free (token_translations
);
353 /* Free the symbol table data structure. */
355 free_merger_functions ();