Index: bison/src/bison/2.4.1/bison-2.4.1-src/src/print-xml.c |
=================================================================== |
--- bison/src/bison/2.4.1/bison-2.4.1-src/src/print-xml.c (revision 0) |
+++ bison/src/bison/2.4.1/bison-2.4.1-src/src/print-xml.c (revision 0) |
@@ -0,0 +1,536 @@ |
+/* Print an xml on generated parser, for Bison, |
+ |
+ Copyright (C) 2007 Free Software Foundation, Inc. |
+ |
+ This file is part of Bison, the GNU Compiler Compiler. |
+ |
+ Bison is free software; you can redistribute it and/or modify |
+ it under the terms of the GNU General Public License as published by |
+ the Free Software Foundation; either version 2, or (at your option) |
+ any later version. |
+ |
+ Bison is distributed in the hope that it will be useful, |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
+ GNU General Public License for more details. |
+ |
+ You should have received a copy of the GNU General Public License |
+ along with Bison; see the file COPYING. If not, write to |
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
+ Boston, MA 02110-1301, USA. */ |
+ |
+#include <config.h> |
+#include "system.h" |
+ |
+#include <stdarg.h> |
+ |
+#include <bitset.h> |
+#include <quotearg.h> |
+ |
+#include "LR0.h" |
+#include "closure.h" |
+#include "conflicts.h" |
+#include "files.h" |
+#include "getargs.h" |
+#include "gram.h" |
+#include "lalr.h" |
+#include "print.h" |
+#include "print-xml.h" |
+#include "reader.h" |
+#include "reduce.h" |
+#include "state.h" |
+#include "symtab.h" |
+#include "tables.h" |
+ |
+static bitset no_reduce_set; |
+struct escape_buf |
+{ |
+ char *ptr; |
+ size_t size; |
+}; |
+static struct escape_buf escape_bufs[2]; |
+ |
+ |
+/*--------------------------------. |
+| Report information on a state. | |
+`--------------------------------*/ |
+ |
+static void |
+print_core (FILE *out, int level, state *s) |
+{ |
+ size_t i; |
+ item_number *sitems = s->items; |
+ size_t snritems = s->nitems; |
+ |
+ /* Output all the items of a state, not only its kernel. */ |
+ closure (sitems, snritems); |
+ sitems = itemset; |
+ snritems = nitemset; |
+ |
+ if (!snritems) { |
+ xml_puts (out, level, "<itemset/>"); |
+ return; |
+ } |
+ |
+ xml_puts (out, level, "<itemset>"); |
+ |
+ for (i = 0; i < snritems; i++) |
+ { |
+ bool printed = false; |
+ item_number *sp; |
+ item_number *sp1; |
+ rule_number r; |
+ |
+ sp1 = sp = ritem + sitems[i]; |
+ |
+ while (*sp >= 0) |
+ sp++; |
+ |
+ r = item_number_as_rule_number (*sp); |
+ sp = rules[r].rhs; |
+ |
+ /* Display the lookahead tokens? */ |
+ if (item_number_is_rule_number (*sp1)) |
+ { |
+ reductions *reds = s->reductions; |
+ int red = state_reduction_find (s, &rules[r]); |
+ /* Print item with lookaheads if there are. */ |
+ if (reds->lookahead_tokens && red != -1) |
+ { |
+ xml_printf (out, level + 1, |
+ "<item rule-number=\"%d\" point=\"%d\">", |
+ rules[r].number, sp1 - sp); |
+ state_rule_lookahead_tokens_print_xml (s, &rules[r], |
+ out, level + 2); |
+ xml_puts (out, level + 1, "</item>"); |
+ printed = true; |
+ } |
+ } |
+ |
+ if (!printed) |
+ { |
+ xml_printf (out, level + 1, |
+ "<item rule-number=\"%d\" point=\"%d\"/>", |
+ rules[r].number, |
+ sp1 - sp); |
+ } |
+ } |
+ xml_puts (out, level, "</itemset>"); |
+} |
+ |
+ |
+/*-----------------------------------------------------------. |
+| Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on | |
+| OUT. | |
+`-----------------------------------------------------------*/ |
+ |
+static void |
+print_transitions (state *s, FILE *out, int level) |
+{ |
+ transitions *trans = s->transitions; |
+ int n = 0; |
+ int i; |
+ |
+ for (i = 0; i < trans->num; i++) |
+ if (!TRANSITION_IS_DISABLED (trans, i)) |
+ { |
+ n++; |
+ } |
+ |
+ /* Nothing to report. */ |
+ if (!n) { |
+ xml_puts (out, level, "<transitions/>"); |
+ return; |
+ } |
+ |
+ /* Report lookahead tokens and shifts. */ |
+ xml_puts (out, level, "<transitions>"); |
+ |
+ for (i = 0; i < trans->num; i++) |
+ if (!TRANSITION_IS_DISABLED (trans, i) |
+ && TRANSITION_IS_SHIFT (trans, i)) |
+ { |
+ symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)]; |
+ char const *tag = sym->tag; |
+ state *s1 = trans->states[i]; |
+ |
+ xml_printf (out, level + 1, |
+ "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>", |
+ xml_escape (tag), s1->number); |
+ } |
+ |
+ for (i = 0; i < trans->num; i++) |
+ if (!TRANSITION_IS_DISABLED (trans, i) |
+ && !TRANSITION_IS_SHIFT (trans, i)) |
+ { |
+ symbol *sym = symbols[TRANSITION_SYMBOL (trans, i)]; |
+ char const *tag = sym->tag; |
+ state *s1 = trans->states[i]; |
+ |
+ xml_printf (out, level + 1, |
+ "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>", |
+ xml_escape (tag), s1->number); |
+ } |
+ |
+ xml_puts (out, level, "</transitions>"); |
+} |
+ |
+ |
+/*--------------------------------------------------------. |
+| Report the explicit errors of S raised from %nonassoc. | |
+`--------------------------------------------------------*/ |
+ |
+static void |
+print_errs (FILE *out, int level, state *s) |
+{ |
+ errs *errp = s->errs; |
+ bool count = false; |
+ int i; |
+ |
+ for (i = 0; i < errp->num; ++i) |
+ if (errp->symbols[i]) |
+ count = true; |
+ |
+ /* Nothing to report. */ |
+ if (!count) { |
+ xml_puts (out, level, "<errors/>"); |
+ return; |
+ } |
+ |
+ /* Report lookahead tokens and errors. */ |
+ xml_puts (out, level, "<errors>"); |
+ for (i = 0; i < errp->num; ++i) |
+ if (errp->symbols[i]) |
+ { |
+ char const *tag = errp->symbols[i]->tag; |
+ xml_printf (out, level + 1, |
+ "<error symbol=\"%s\">nonassociative</error>", |
+ xml_escape (tag)); |
+ } |
+ xml_puts (out, level, "</errors>"); |
+} |
+ |
+ |
+/*-------------------------------------------------------------------------. |
+| Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). | |
+| If not ENABLED, the rule is masked by a shift or a reduce (S/R and | |
+| R/R conflicts). | |
+`-------------------------------------------------------------------------*/ |
+ |
+static void |
+print_reduction (FILE *out, int level, char const *lookahead_token, |
+ rule *r, bool enabled) |
+{ |
+ if (r->number) |
+ xml_printf (out, level, |
+ "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>", |
+ xml_escape (lookahead_token), |
+ r->number, |
+ enabled ? "true" : "false"); |
+ else |
+ xml_printf (out, level, |
+ "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>", |
+ xml_escape (lookahead_token), |
+ enabled ? "true" : "false"); |
+} |
+ |
+ |
+/*-------------------------------------------. |
+| Report on OUT the reduction actions of S. | |
+`-------------------------------------------*/ |
+ |
+static void |
+print_reductions (FILE *out, int level, state *s) |
+{ |
+ transitions *trans = s->transitions; |
+ reductions *reds = s->reductions; |
+ rule *default_rule = NULL; |
+ int report = false; |
+ int i, j; |
+ |
+ if (reds->num == 0) { |
+ xml_puts (out, level, "<reductions/>"); |
+ return; |
+ } |
+ |
+ if (yydefact[s->number] != 0) |
+ default_rule = &rules[yydefact[s->number] - 1]; |
+ |
+ bitset_zero (no_reduce_set); |
+ FOR_EACH_SHIFT (trans, i) |
+ bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); |
+ for (i = 0; i < s->errs->num; ++i) |
+ if (s->errs->symbols[i]) |
+ bitset_set (no_reduce_set, s->errs->symbols[i]->number); |
+ |
+ if (default_rule) |
+ report = true; |
+ |
+ if (reds->lookahead_tokens) |
+ for (i = 0; i < ntokens; i++) |
+ { |
+ bool count = bitset_test (no_reduce_set, i); |
+ |
+ for (j = 0; j < reds->num; ++j) |
+ if (bitset_test (reds->lookahead_tokens[j], i)) |
+ { |
+ if (! count) |
+ { |
+ if (reds->rules[j] != default_rule) |
+ report = true; |
+ count = true; |
+ } |
+ else |
+ { |
+ report = true; |
+ } |
+ } |
+ } |
+ |
+ /* Nothing to report. */ |
+ if (!report) { |
+ xml_puts (out, level, "<reductions/>"); |
+ return; |
+ } |
+ |
+ xml_puts (out, level, "<reductions>"); |
+ |
+ /* Report lookahead tokens (or $default) and reductions. */ |
+ if (reds->lookahead_tokens) |
+ for (i = 0; i < ntokens; i++) |
+ { |
+ bool defaulted = false; |
+ bool count = bitset_test (no_reduce_set, i); |
+ |
+ for (j = 0; j < reds->num; ++j) |
+ if (bitset_test (reds->lookahead_tokens[j], i)) |
+ { |
+ if (! count) |
+ { |
+ if (reds->rules[j] != default_rule) |
+ print_reduction (out, level + 1, symbols[i]->tag, |
+ reds->rules[j], true); |
+ else |
+ defaulted = true; |
+ count = true; |
+ } |
+ else |
+ { |
+ if (defaulted) |
+ print_reduction (out, level + 1, symbols[i]->tag, |
+ default_rule, true); |
+ defaulted = false; |
+ print_reduction (out, level + 1, symbols[i]->tag, |
+ reds->rules[j], false); |
+ } |
+ } |
+ } |
+ |
+ if (default_rule) |
+ print_reduction (out, level + 1, |
+ "$default", default_rule, true); |
+ |
+ xml_puts (out, level, "</reductions>"); |
+} |
+ |
+ |
+/*--------------------------------------------------------------. |
+| Report on OUT all the actions (shifts, gotos, reductions, and | |
+| explicit erros from %nonassoc) of S. | |
+`--------------------------------------------------------------*/ |
+ |
+static void |
+print_actions (FILE *out, int level, state *s) |
+{ |
+ xml_puts (out, level, "<actions>"); |
+ print_transitions (s, out, level + 1); |
+ print_errs (out, level + 1, s); |
+ print_reductions (out, level + 1, s); |
+ xml_puts (out, level, "</actions>"); |
+} |
+ |
+ |
+/*----------------------------------. |
+| Report all the data on S on OUT. | |
+`----------------------------------*/ |
+ |
+static void |
+print_state (FILE *out, int level, state *s) |
+{ |
+ fputc ('\n', out); |
+ xml_printf (out, level, "<state number=\"%d\">", s->number); |
+ print_core (out, level + 1, s); |
+ print_actions (out, level + 1, s); |
+ if (s->solved_conflicts_xml) |
+ { |
+ xml_puts (out, level + 1, "<solved-conflicts>"); |
+ fputs (s->solved_conflicts_xml, out); |
+ xml_puts (out, level + 1, "</solved-conflicts>"); |
+ } |
+ else |
+ xml_puts (out, level + 1, "<solved-conflicts/>"); |
+ xml_puts (out, level, "</state>"); |
+} |
+ |
+ |
+/*-----------------------------------------. |
+| Print information on the whole grammar. | |
+`-----------------------------------------*/ |
+ |
+static void |
+print_grammar (FILE *out, int level) |
+{ |
+ symbol_number i; |
+ |
+ fputc ('\n', out); |
+ xml_puts (out, level, "<grammar>"); |
+ grammar_rules_print_xml (out, level); |
+ |
+ /* Terminals */ |
+ xml_puts (out, level + 1, "<terminals>"); |
+ for (i = 0; i < max_user_token_number + 1; i++) |
+ if (token_translations[i] != undeftoken->number) |
+ { |
+ char const *tag = symbols[token_translations[i]]->tag; |
+ int precedence = symbols[token_translations[i]]->prec; |
+ assoc associativity = symbols[token_translations[i]]->assoc; |
+ xml_indent (out, level + 2); |
+ fprintf (out, |
+ "<terminal symbol-number=\"%d\" token-number=\"%d\"" |
+ " name=\"%s\" usefulness=\"%s\"", |
+ token_translations[i], i, xml_escape (tag), |
+ reduce_token_unused_in_grammar (token_translations[i]) |
+ ? "unused-in-grammar" : "useful"); |
+ if (precedence) |
+ fprintf (out, " prec=\"%d\"", precedence); |
+ if (associativity != undef_assoc) |
+ fprintf (out, " assoc=\"%s\"", assoc_to_string (associativity) + 1); |
+ fputs ("/>\n", out); |
+ } |
+ xml_puts (out, level + 1, "</terminals>"); |
+ |
+ /* Nonterminals */ |
+ xml_puts (out, level + 1, "<nonterminals>"); |
+ for (i = ntokens; i < nsyms + nuseless_nonterminals; i++) |
+ { |
+ char const *tag = symbols[i]->tag; |
+ xml_printf (out, level + 2, |
+ "<nonterminal symbol-number=\"%d\" name=\"%s\"" |
+ " usefulness=\"%s\"/>", |
+ i, xml_escape (tag), |
+ reduce_nonterminal_useless_in_grammar (i) |
+ ? "useless-in-grammar" : "useful"); |
+ } |
+ xml_puts (out, level + 1, "</nonterminals>"); |
+ xml_puts (out, level, "</grammar>"); |
+} |
+ |
+void |
+xml_indent (FILE *out, int level) |
+{ |
+ int i; |
+ for (i = 0; i < level; i++) |
+ fputs (" ", out); |
+} |
+ |
+void |
+xml_puts (FILE *out, int level, char const *s) |
+{ |
+ xml_indent (out, level); |
+ fputs (s, out); |
+ fputc ('\n', out); |
+} |
+ |
+void |
+xml_printf (FILE *out, int level, char const *fmt, ...) |
+{ |
+ va_list arglist; |
+ |
+ xml_indent (out, level); |
+ |
+ va_start (arglist, fmt); |
+ vfprintf (out, fmt, arglist); |
+ va_end (arglist); |
+ |
+ fputc ('\n', out); |
+} |
+ |
+static char const * |
+xml_escape_string (struct escape_buf *buf, char const *str) |
+{ |
+ size_t len = strlen (str); |
+ size_t max_expansion = sizeof """ - 1; |
+ char *p; |
+ |
+ if (buf->size <= max_expansion * len) |
+ { |
+ buf->size = max_expansion * len + 1; |
+ buf->ptr = x2realloc (buf->ptr, &buf->size); |
+ } |
+ p = buf->ptr; |
+ |
+ for (; *str; str++) |
+ switch (*str) |
+ { |
+ default: *p++ = *str; break; |
+ case '&': p = stpcpy (p, "&" ); break; |
+ case '<': p = stpcpy (p, "<" ); break; |
+ case '>': p = stpcpy (p, ">" ); break; |
+ case '"': p = stpcpy (p, """); break; |
+ } |
+ |
+ *p = '\0'; |
+ return buf->ptr; |
+} |
+ |
+char const * |
+xml_escape_n (int n, char const *str) |
+{ |
+ return xml_escape_string (escape_bufs + n, str); |
+} |
+ |
+char const * |
+xml_escape (char const *str) |
+{ |
+ return xml_escape_n (0, str); |
+} |
+ |
+void |
+print_xml (void) |
+{ |
+ state_number i; |
+ int level = 0; |
+ |
+ FILE *out = xfopen (spec_xml_file, "w"); |
+ |
+ fputs ("<?xml version=\"1.0\"?>\n\n", out); |
+ xml_printf (out, level, "<bison-xml-report version=\"%s\">", |
+ xml_escape (VERSION)); |
+ |
+ fputc ('\n', out); |
+ xml_printf (out, level + 1, "<filename>%s</filename>", |
+ xml_escape (grammar_file)); |
+ |
+ /* print grammar */ |
+ print_grammar (out, level + 1); |
+ |
+ new_closure (nritems); |
+ no_reduce_set = bitset_create (ntokens, BITSET_FIXED); |
+ |
+ /* print automaton */ |
+ fputc ('\n', out); |
+ xml_puts (out, level + 1, "<automaton>"); |
+ for (i = 0; i < nstates; i++) |
+ print_state (out, level + 2, states[i]); |
+ xml_puts (out, level + 1, "</automaton>"); |
+ |
+ bitset_free (no_reduce_set); |
+ free_closure (); |
+ |
+ xml_puts (out, 0, "</bison-xml-report>"); |
+ |
+ free (escape_bufs[0].ptr); |
+ free (escape_bufs[1].ptr); |
+ |
+ xfclose (out); |
+} |
Property changes on: bison\src\bison\2.4.1\bison-2.4.1-src\src\print-xml.c |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |