]>
git.saurik.com Git - bison.git/blob - src/print-xml.c
1 /* Print an xml on generated parser, for Bison,
3 Copyright (C) 2007 Free Software Foundation, Inc.
5 This file is part of Bison, the GNU Compiler Compiler.
7 Bison is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bison is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
32 #include "conflicts.h"
38 #include "print-xml.h"
45 static bitset no_reduce_set
;
48 /*----------------------------.
49 | Print rules never reduced. |
50 `-----------------------------*/
53 print_rules_never_reduced (FILE *out
, int level
)
58 for (r
= 0; r
< nrules
+ nuseless_productions
; r
++)
60 if (rule_never_reduced_p (&rules
[r
]))
68 xml_puts (out
, level
, "<rules-never-reduced>");
69 grammar_rules_partial_print_xml (out
, level
- 1,
70 false, rule_never_reduced_p
);
71 xml_puts (out
, level
, "</rules-never-reduced>");
74 xml_puts (out
, level
, "<rules-never-reduced/>");
77 /*--------------------------------.
78 | Report information on a state. |
79 `--------------------------------*/
82 print_core (FILE *out
, int level
, state
*s
)
85 item_number
*sitems
= s
->items
;
86 size_t snritems
= s
->nitems
;
88 /* Output all the items of a state, not only its kernel. */
89 if (report_flag
& report_itemsets
)
91 closure (sitems
, snritems
);
97 xml_puts (out
, level
, "<itemset/>");
101 xml_puts (out
, level
, "<itemset>");
103 for (i
= 0; i
< snritems
; i
++)
109 sp1
= sp
= ritem
+ sitems
[i
];
114 r
= item_number_as_rule_number (*sp
);
116 xml_printf (out
, level
+ 1, "<rule number=\"%d\">",
119 rule_lhs_print_xml (&rules
[r
], out
, level
+ 2);
121 xml_puts (out
, level
+ 2, "<rhs>");
122 for (sp
= rules
[r
].rhs
; sp
< sp1
; sp
++)
123 xml_printf (out
, level
+ 3, "<symbol class=\"%s\">%s</symbol>",
124 symbol_class_get_string (symbols
[*sp
]),
125 xml_escape (symbols
[*sp
]->tag
));
126 xml_puts (out
, level
+ 3, "<point/>");
127 for (/* Nothing */; *sp
>= 0; ++sp
)
128 xml_printf (out
, level
+ 3, "<symbol class=\"%s\">%s</symbol>",
129 symbol_class_get_string (symbols
[*sp
]),
130 xml_escape (symbols
[*sp
]->tag
));
132 xml_puts (out
, level
+ 2, "</rhs>");
134 /* Display the lookahead tokens? */
135 if (report_flag
& report_lookahead_tokens
)
136 state_rule_lookahead_tokens_print_xml (s
, &rules
[r
], out
, level
+ 2);
138 xml_puts (out
, level
+ 1, "</rule>");
140 xml_puts (out
, level
, "</itemset>");
144 /*-----------------------------------------------------------.
145 | Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on |
147 `-----------------------------------------------------------*/
150 print_transitions (state
*s
, FILE *out
, int level
)
152 transitions
*trans
= s
->transitions
;
156 for (i
= 0; i
< trans
->num
; i
++)
157 if (!TRANSITION_IS_DISABLED (trans
, i
))
162 /* Nothing to report. */
164 xml_puts (out
, level
, "<transitions/>");
168 /* Report lookahead tokens and shifts. */
169 xml_puts (out
, level
, "<transitions>");
171 for (i
= 0; i
< trans
->num
; i
++)
172 if (!TRANSITION_IS_DISABLED (trans
, i
)
173 && TRANSITION_IS_SHIFT (trans
, i
))
175 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
176 char const *tag
= sym
->tag
;
177 state
*s1
= trans
->states
[i
];
179 xml_printf (out
, level
+ 1,
180 "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>",
181 xml_escape (tag
), s1
->number
);
184 for (i
= 0; i
< trans
->num
; i
++)
185 if (!TRANSITION_IS_DISABLED (trans
, i
)
186 && !TRANSITION_IS_SHIFT (trans
, i
))
188 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
189 char const *tag
= sym
->tag
;
190 state
*s1
= trans
->states
[i
];
192 xml_printf (out
, level
+ 1,
193 "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>",
194 xml_escape (tag
), s1
->number
);
197 xml_puts (out
, level
, "</transitions>");
201 /*--------------------------------------------------------.
202 | Report the explicit errors of S raised from %nonassoc. |
203 `--------------------------------------------------------*/
206 print_errs (FILE *out
, int level
, state
*s
)
208 errs
*errp
= s
->errs
;
212 for (i
= 0; i
< errp
->num
; ++i
)
213 if (errp
->symbols
[i
])
216 /* Nothing to report. */
218 xml_puts (out
, level
, "<errors/>");
222 /* Report lookahead tokens and errors. */
223 xml_puts (out
, level
, "<errors>");
224 for (i
= 0; i
< errp
->num
; ++i
)
225 if (errp
->symbols
[i
])
227 char const *tag
= errp
->symbols
[i
]->tag
;
228 xml_printf (out
, level
+ 1,
229 "<error symbol=\"%s\">nonassociative</error>",
232 xml_puts (out
, level
, "</errors>");
236 /*-------------------------------------------------------------------------.
237 | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
238 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
240 `-------------------------------------------------------------------------*/
243 print_reduction (FILE *out
, int level
, char const *lookahead_token
,
244 rule
*r
, bool enabled
)
247 xml_printf (out
, level
,
248 "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
249 xml_escape (lookahead_token
),
251 enabled
? "true" : "false");
253 xml_printf (out
, level
,
254 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
255 xml_escape (lookahead_token
),
256 enabled
? "true" : "false");
260 /*-------------------------------------------.
261 | Report on OUT the reduction actions of S. |
262 `-------------------------------------------*/
265 print_reductions (FILE *out
, int level
, state
*s
)
267 transitions
*trans
= s
->transitions
;
268 reductions
*reds
= s
->reductions
;
269 rule
*default_rule
= NULL
;
273 if (reds
->num
== 0) {
274 xml_puts (out
, level
, "<reductions/>");
278 if (yydefact
[s
->number
] != 0)
279 default_rule
= &rules
[yydefact
[s
->number
] - 1];
281 bitset_zero (no_reduce_set
);
282 FOR_EACH_SHIFT (trans
, i
)
283 bitset_set (no_reduce_set
, TRANSITION_SYMBOL (trans
, i
));
284 for (i
= 0; i
< s
->errs
->num
; ++i
)
285 if (s
->errs
->symbols
[i
])
286 bitset_set (no_reduce_set
, s
->errs
->symbols
[i
]->number
);
291 if (reds
->lookahead_tokens
)
292 for (i
= 0; i
< ntokens
; i
++)
294 bool count
= bitset_test (no_reduce_set
, i
);
296 for (j
= 0; j
< reds
->num
; ++j
)
297 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
301 if (reds
->rules
[j
] != default_rule
)
312 /* Nothing to report. */
314 xml_puts (out
, level
, "<reductions/>");
318 xml_puts (out
, level
, "<reductions>");
320 /* Report lookahead tokens (or $default) and reductions. */
321 if (reds
->lookahead_tokens
)
322 for (i
= 0; i
< ntokens
; i
++)
324 bool defaulted
= false;
325 bool count
= bitset_test (no_reduce_set
, i
);
327 for (j
= 0; j
< reds
->num
; ++j
)
328 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
332 if (reds
->rules
[j
] != default_rule
)
333 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
334 reds
->rules
[j
], true);
342 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
345 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
346 reds
->rules
[j
], false);
352 print_reduction (out
, level
+ 1,
353 "$default", default_rule
, true);
355 xml_puts (out
, level
, "</reductions>");
359 /*--------------------------------------------------------------.
360 | Report on OUT all the actions (shifts, gotos, reductions, and |
361 | explicit erros from %nonassoc) of S. |
362 `--------------------------------------------------------------*/
365 print_actions (FILE *out
, int level
, state
*s
)
367 xml_puts (out
, level
, "<actions>");
368 print_transitions (s
, out
, level
+ 1);
369 print_errs (out
, level
+ 1, s
);
370 print_reductions (out
, level
+ 1, s
);
371 xml_puts (out
, level
, "</actions>");
375 /*----------------------------------.
376 | Report all the data on S on OUT. |
377 `----------------------------------*/
380 print_state (FILE *out
, int level
, state
*s
)
383 xml_printf (out
, level
, "<state number=\"%d\">", s
->number
);
384 print_core (out
, level
+ 1, s
);
385 print_actions (out
, level
+ 1, s
);
386 if ((report_flag
& report_solved_conflicts
) && s
->solved_conflicts_xml
)
388 xml_puts (out
, level
+ 1, "<solved-conflicts>");
389 fputs (s
->solved_conflicts_xml
, out
);
390 xml_puts (out
, level
+ 1, "</solved-conflicts>");
393 xml_puts (out
, level
+ 1, "<solved-conflicts/>");
394 xml_puts (out
, level
, "</state>");
398 /*-----------------------------------------.
399 | Print information on the whole grammar. |
400 `-----------------------------------------*/
403 print_grammar (FILE *out
, int level
)
408 xml_puts (out
, level
, "<grammar>");
409 grammar_rules_print_xml (out
, level
);
412 xml_puts (out
, level
+ 1, "<terminals>");
413 for (i
= 0; i
< max_user_token_number
+ 1; i
++)
414 if (token_translations
[i
] != undeftoken
->number
)
416 char const *tag
= symbols
[token_translations
[i
]]->tag
;
420 xml_printf (out
, level
+ 2,
421 "<terminal type=\"%d\" symbol=\"%s\">",
422 i
, xml_escape (tag
));
424 for (r
= 0; r
< nrules
; r
++)
425 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
426 if (item_number_as_symbol_number (*rhsp
) == token_translations
[i
])
428 xml_printf (out
, level
+ 3, "<rule>%d</rule>", r
);
431 xml_puts (out
, level
+ 2, "</terminal>");
433 xml_puts (out
, level
+ 1, "</terminals>");
436 xml_puts (out
, level
+ 1, "<nonterminals>");
437 for (i
= ntokens
; i
< nsyms
; i
++)
439 int left_count
= 0, right_count
= 0;
441 char const *tag
= symbols
[i
]->tag
;
443 for (r
= 0; r
< nrules
; r
++)
446 if (rules
[r
].lhs
->number
== i
)
448 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
449 if (item_number_as_symbol_number (*rhsp
) == i
)
456 xml_printf (out
, level
+ 2,
457 "<nonterminal type=\"%d\" symbol=\"%s\">",
458 i
, xml_escape (tag
));
462 xml_puts (out
, level
+ 3, "<left>");
463 for (r
= 0; r
< nrules
; r
++)
465 if (rules
[r
].lhs
->number
== i
)
466 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
468 xml_puts (out
, level
+ 3, "</left>");
473 xml_puts (out
, level
+ 3, "<right>");
474 for (r
= 0; r
< nrules
; r
++)
477 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
478 if (item_number_as_symbol_number (*rhsp
) == i
)
480 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
484 xml_puts (out
, level
+ 3, "</right>");
487 xml_puts (out
, level
+ 2, "</nonterminal>");
489 xml_puts (out
, level
+ 1, "</nonterminals>");
490 xml_puts (out
, level
, "</grammar>");
494 xml_puts (FILE *out
, int level
, char const *s
)
497 for (i
= 0; i
< level
; i
++)
504 xml_printf (FILE *out
, int level
, char const *fmt
, ...)
509 for (i
= 0; i
< level
; i
++)
512 va_start (arglist
, fmt
);
513 vfprintf (out
, fmt
, arglist
);
526 xml_escape_string (struct escape_buf
*buf
, char const *str
)
528 size_t len
= strlen (str
);
529 size_t max_expansion
= sizeof """ - 1;
532 if (buf
->size
<= max_expansion
* len
)
534 buf
->size
= max_expansion
* len
+ 1;
535 buf
->ptr
= x2realloc (buf
->ptr
, &buf
->size
);
542 default: *p
++ = *str
; break;
543 case '&': p
= stpcpy (p
, "&" ); break;
544 case '<': p
= stpcpy (p
, "<" ); break;
545 case '>': p
= stpcpy (p
, ">" ); break;
546 case '"': p
= stpcpy (p
, """); break;
554 xml_escape_n (int n
, char const *str
)
556 static struct escape_buf buf
[2];
557 return xml_escape_string (buf
+ n
, str
);
561 xml_escape (char const *str
)
563 return xml_escape_n (0, str
);
572 FILE *out
= xfopen (spec_xml_file
, "w");
574 fputs ("<?xml version=\"1.0\"?>\n\n", out
);
575 xml_printf (out
, level
, "<bison-xml-report version=\"%s\">",
576 xml_escape (VERSION
));
579 xml_printf (out
, level
+ 1, "<filename>%s</filename>",
580 xml_escape (grammar_file
));
582 /* print reductions */
583 reduce_xml (out
, level
+ 1);
585 /* print rules never reduced */
586 print_rules_never_reduced (out
, level
+ 1);
588 /* print conflicts */
589 conflicts_output_xml (out
, level
+ 1);
592 print_grammar (out
, level
+ 1);
594 if (report_flag
& report_itemsets
)
595 new_closure (nritems
);
596 no_reduce_set
= bitset_create (ntokens
, BITSET_FIXED
);
598 /* print automaton */
600 xml_puts (out
, level
+ 1, "<automaton>");
601 for (i
= 0; i
< nstates
; i
++)
602 print_state (out
, level
+ 2, states
[i
]);
603 xml_puts (out
, level
+ 1, "</automaton>");
605 bitset_free (no_reduce_set
);
606 if (report_flag
& report_itemsets
)
609 xml_puts (out
, 0, "</bison-xml-report>");