]>
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
;
51 static struct escape_buf escape_bufs
[2];
54 /*----------------------------.
55 | Print rules never reduced. |
56 `-----------------------------*/
59 print_rules_never_reduced (FILE *out
, int level
)
64 for (r
= 0; r
< nrules
+ nuseless_productions
; r
++)
66 if (rule_never_reduced_p (&rules
[r
]))
74 xml_puts (out
, level
, "<rules-never-reduced>");
75 grammar_rules_partial_print_xml (out
, level
- 1,
76 false, rule_never_reduced_p
);
77 xml_puts (out
, level
, "</rules-never-reduced>");
80 xml_puts (out
, level
, "<rules-never-reduced/>");
83 /*--------------------------------.
84 | Report information on a state. |
85 `--------------------------------*/
88 print_core (FILE *out
, int level
, state
*s
)
91 item_number
*sitems
= s
->items
;
92 size_t snritems
= s
->nitems
;
94 /* Output all the items of a state, not only its kernel. */
95 if (report_flag
& report_itemsets
)
97 closure (sitems
, snritems
);
103 xml_puts (out
, level
, "<itemset/>");
107 xml_puts (out
, level
, "<itemset>");
109 for (i
= 0; i
< snritems
; i
++)
111 bool printed
= false;
116 sp1
= sp
= ritem
+ sitems
[i
];
121 r
= item_number_as_rule_number (*sp
);
124 /* Display the lookahead tokens? */
125 if (report_flag
& report_lookahead_tokens
126 && item_number_is_rule_number (*sp1
))
128 reductions
*reds
= s
->reductions
;
129 int red
= state_reduction_find (s
, &rules
[r
]);
130 /* Print item with lookaheads if there are. */
131 if (reds
->lookahead_tokens
&& red
!= -1)
133 xml_printf (out
, level
+ 1,
134 "<item rule-number=\"%d\" point=\"%d\">",
135 rules
[r
].number
, sp1
- sp
);
136 state_rule_lookahead_tokens_print_xml (s
, &rules
[r
],
138 xml_puts (out
, level
+ 1, "</item>");
145 xml_printf (out
, level
+ 1,
146 "<item rule-number=\"%d\" point=\"%d\"/>",
151 xml_puts (out
, level
, "</itemset>");
155 /*-----------------------------------------------------------.
156 | Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on |
158 `-----------------------------------------------------------*/
161 print_transitions (state
*s
, FILE *out
, int level
)
163 transitions
*trans
= s
->transitions
;
167 for (i
= 0; i
< trans
->num
; i
++)
168 if (!TRANSITION_IS_DISABLED (trans
, i
))
173 /* Nothing to report. */
175 xml_puts (out
, level
, "<transitions/>");
179 /* Report lookahead tokens and shifts. */
180 xml_puts (out
, level
, "<transitions>");
182 for (i
= 0; i
< trans
->num
; i
++)
183 if (!TRANSITION_IS_DISABLED (trans
, i
)
184 && TRANSITION_IS_SHIFT (trans
, i
))
186 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
187 char const *tag
= sym
->tag
;
188 state
*s1
= trans
->states
[i
];
190 xml_printf (out
, level
+ 1,
191 "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>",
192 xml_escape (tag
), s1
->number
);
195 for (i
= 0; i
< trans
->num
; i
++)
196 if (!TRANSITION_IS_DISABLED (trans
, i
)
197 && !TRANSITION_IS_SHIFT (trans
, i
))
199 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
200 char const *tag
= sym
->tag
;
201 state
*s1
= trans
->states
[i
];
203 xml_printf (out
, level
+ 1,
204 "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>",
205 xml_escape (tag
), s1
->number
);
208 xml_puts (out
, level
, "</transitions>");
212 /*--------------------------------------------------------.
213 | Report the explicit errors of S raised from %nonassoc. |
214 `--------------------------------------------------------*/
217 print_errs (FILE *out
, int level
, state
*s
)
219 errs
*errp
= s
->errs
;
223 for (i
= 0; i
< errp
->num
; ++i
)
224 if (errp
->symbols
[i
])
227 /* Nothing to report. */
229 xml_puts (out
, level
, "<errors/>");
233 /* Report lookahead tokens and errors. */
234 xml_puts (out
, level
, "<errors>");
235 for (i
= 0; i
< errp
->num
; ++i
)
236 if (errp
->symbols
[i
])
238 char const *tag
= errp
->symbols
[i
]->tag
;
239 xml_printf (out
, level
+ 1,
240 "<error symbol=\"%s\">nonassociative</error>",
243 xml_puts (out
, level
, "</errors>");
247 /*-------------------------------------------------------------------------.
248 | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
249 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
251 `-------------------------------------------------------------------------*/
254 print_reduction (FILE *out
, int level
, char const *lookahead_token
,
255 rule
*r
, bool enabled
)
258 xml_printf (out
, level
,
259 "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
260 xml_escape (lookahead_token
),
262 enabled
? "true" : "false");
264 xml_printf (out
, level
,
265 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
266 xml_escape (lookahead_token
),
267 enabled
? "true" : "false");
271 /*-------------------------------------------.
272 | Report on OUT the reduction actions of S. |
273 `-------------------------------------------*/
276 print_reductions (FILE *out
, int level
, state
*s
)
278 transitions
*trans
= s
->transitions
;
279 reductions
*reds
= s
->reductions
;
280 rule
*default_rule
= NULL
;
284 if (reds
->num
== 0) {
285 xml_puts (out
, level
, "<reductions/>");
289 if (yydefact
[s
->number
] != 0)
290 default_rule
= &rules
[yydefact
[s
->number
] - 1];
292 bitset_zero (no_reduce_set
);
293 FOR_EACH_SHIFT (trans
, i
)
294 bitset_set (no_reduce_set
, TRANSITION_SYMBOL (trans
, i
));
295 for (i
= 0; i
< s
->errs
->num
; ++i
)
296 if (s
->errs
->symbols
[i
])
297 bitset_set (no_reduce_set
, s
->errs
->symbols
[i
]->number
);
302 if (reds
->lookahead_tokens
)
303 for (i
= 0; i
< ntokens
; i
++)
305 bool count
= bitset_test (no_reduce_set
, i
);
307 for (j
= 0; j
< reds
->num
; ++j
)
308 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
312 if (reds
->rules
[j
] != default_rule
)
323 /* Nothing to report. */
325 xml_puts (out
, level
, "<reductions/>");
329 xml_puts (out
, level
, "<reductions>");
331 /* Report lookahead tokens (or $default) and reductions. */
332 if (reds
->lookahead_tokens
)
333 for (i
= 0; i
< ntokens
; i
++)
335 bool defaulted
= false;
336 bool count
= bitset_test (no_reduce_set
, i
);
338 for (j
= 0; j
< reds
->num
; ++j
)
339 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
343 if (reds
->rules
[j
] != default_rule
)
344 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
345 reds
->rules
[j
], true);
353 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
356 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
357 reds
->rules
[j
], false);
363 print_reduction (out
, level
+ 1,
364 "$default", default_rule
, true);
366 xml_puts (out
, level
, "</reductions>");
370 /*--------------------------------------------------------------.
371 | Report on OUT all the actions (shifts, gotos, reductions, and |
372 | explicit erros from %nonassoc) of S. |
373 `--------------------------------------------------------------*/
376 print_actions (FILE *out
, int level
, state
*s
)
378 xml_puts (out
, level
, "<actions>");
379 print_transitions (s
, out
, level
+ 1);
380 print_errs (out
, level
+ 1, s
);
381 print_reductions (out
, level
+ 1, s
);
382 xml_puts (out
, level
, "</actions>");
386 /*----------------------------------.
387 | Report all the data on S on OUT. |
388 `----------------------------------*/
391 print_state (FILE *out
, int level
, state
*s
)
394 xml_printf (out
, level
, "<state number=\"%d\">", s
->number
);
395 print_core (out
, level
+ 1, s
);
396 print_actions (out
, level
+ 1, s
);
397 if ((report_flag
& report_solved_conflicts
) && s
->solved_conflicts_xml
)
399 xml_puts (out
, level
+ 1, "<solved-conflicts>");
400 fputs (s
->solved_conflicts_xml
, out
);
401 xml_puts (out
, level
+ 1, "</solved-conflicts>");
404 xml_puts (out
, level
+ 1, "<solved-conflicts/>");
405 xml_puts (out
, level
, "</state>");
409 /*-----------------------------------------.
410 | Print information on the whole grammar. |
411 `-----------------------------------------*/
414 print_grammar (FILE *out
, int level
)
419 xml_puts (out
, level
, "<grammar>");
420 grammar_rules_print_xml (out
, level
);
423 xml_puts (out
, level
+ 1, "<terminals>");
424 for (i
= 0; i
< max_user_token_number
+ 1; i
++)
425 if (token_translations
[i
] != undeftoken
->number
)
427 char const *tag
= symbols
[token_translations
[i
]]->tag
;
431 xml_printf (out
, level
+ 2,
432 "<terminal symbol-number=\"%d\" token-number=\"%d\""
434 token_translations
[i
], i
, xml_escape (tag
));
436 for (r
= 0; r
< nrules
; r
++)
437 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
438 if (item_number_as_symbol_number (*rhsp
) == token_translations
[i
])
440 xml_printf (out
, level
+ 3, "<rule>%d</rule>", r
);
443 xml_puts (out
, level
+ 2, "</terminal>");
445 xml_puts (out
, level
+ 1, "</terminals>");
448 xml_puts (out
, level
+ 1, "<nonterminals>");
449 for (i
= ntokens
; i
< nsyms
; i
++)
451 int left_count
= 0, right_count
= 0;
453 char const *tag
= symbols
[i
]->tag
;
455 for (r
= 0; r
< nrules
; r
++)
458 if (rules
[r
].lhs
->number
== i
)
460 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
461 if (item_number_as_symbol_number (*rhsp
) == i
)
468 xml_printf (out
, level
+ 2,
469 "<nonterminal symbol-number=\"%d\" name=\"%s\">",
470 i
, xml_escape (tag
));
474 xml_puts (out
, level
+ 3, "<left>");
475 for (r
= 0; r
< nrules
; r
++)
477 if (rules
[r
].lhs
->number
== i
)
478 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
480 xml_puts (out
, level
+ 3, "</left>");
485 xml_puts (out
, level
+ 3, "<right>");
486 for (r
= 0; r
< nrules
; r
++)
489 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
490 if (item_number_as_symbol_number (*rhsp
) == i
)
492 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
496 xml_puts (out
, level
+ 3, "</right>");
499 xml_puts (out
, level
+ 2, "</nonterminal>");
501 xml_puts (out
, level
+ 1, "</nonterminals>");
502 xml_puts (out
, level
, "</grammar>");
506 xml_puts (FILE *out
, int level
, char const *s
)
509 for (i
= 0; i
< level
; i
++)
516 xml_printf (FILE *out
, int level
, char const *fmt
, ...)
521 for (i
= 0; i
< level
; i
++)
524 va_start (arglist
, fmt
);
525 vfprintf (out
, fmt
, arglist
);
532 xml_escape_string (struct escape_buf
*buf
, char const *str
)
534 size_t len
= strlen (str
);
535 size_t max_expansion
= sizeof """ - 1;
538 if (buf
->size
<= max_expansion
* len
)
540 buf
->size
= max_expansion
* len
+ 1;
541 buf
->ptr
= x2realloc (buf
->ptr
, &buf
->size
);
548 default: *p
++ = *str
; break;
549 case '&': p
= stpcpy (p
, "&" ); break;
550 case '<': p
= stpcpy (p
, "<" ); break;
551 case '>': p
= stpcpy (p
, ">" ); break;
552 case '"': p
= stpcpy (p
, """); break;
560 xml_escape_n (int n
, char const *str
)
562 return xml_escape_string (escape_bufs
+ n
, str
);
566 xml_escape (char const *str
)
568 return xml_escape_n (0, str
);
577 FILE *out
= xfopen (spec_xml_file
, "w");
579 fputs ("<?xml version=\"1.0\"?>\n\n", out
);
580 xml_printf (out
, level
, "<bison-xml-report version=\"%s\">",
581 xml_escape (VERSION
));
584 xml_printf (out
, level
+ 1, "<filename>%s</filename>",
585 xml_escape (grammar_file
));
587 /* print reductions */
588 reduce_xml (out
, level
+ 1);
590 /* print rules never reduced */
591 print_rules_never_reduced (out
, level
+ 1);
594 print_grammar (out
, level
+ 1);
596 if (report_flag
& report_itemsets
)
597 new_closure (nritems
);
598 no_reduce_set
= bitset_create (ntokens
, BITSET_FIXED
);
600 /* print automaton */
602 xml_puts (out
, level
+ 1, "<automaton>");
603 for (i
= 0; i
< nstates
; i
++)
604 print_state (out
, level
+ 2, states
[i
]);
605 xml_puts (out
, level
+ 1, "</automaton>");
607 bitset_free (no_reduce_set
);
608 if (report_flag
& report_itemsets
)
611 xml_puts (out
, 0, "</bison-xml-report>");
613 free (escape_bufs
[0].ptr
);
614 free (escape_bufs
[1].ptr
);