]>
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
++)
115 sp1
= sp
= ritem
+ sitems
[i
];
120 r
= item_number_as_rule_number (*sp
);
122 xml_printf (out
, level
+ 1, "<rule number=\"%d\">",
125 rule_lhs_print_xml (&rules
[r
], out
, level
+ 2);
127 xml_puts (out
, level
+ 2, "<rhs>");
128 for (sp
= rules
[r
].rhs
; sp
< sp1
; sp
++)
129 xml_printf (out
, level
+ 3, "<symbol class=\"%s\">%s</symbol>",
130 symbol_class_get_string (symbols
[*sp
]),
131 xml_escape (symbols
[*sp
]->tag
));
132 xml_puts (out
, level
+ 3, "<point/>");
133 for (/* Nothing */; *sp
>= 0; ++sp
)
134 xml_printf (out
, level
+ 3, "<symbol class=\"%s\">%s</symbol>",
135 symbol_class_get_string (symbols
[*sp
]),
136 xml_escape (symbols
[*sp
]->tag
));
138 xml_puts (out
, level
+ 2, "</rhs>");
140 /* Display the lookahead tokens? */
141 if (report_flag
& report_lookahead_tokens
)
142 state_rule_lookahead_tokens_print_xml (s
, &rules
[r
], out
, level
+ 2);
144 xml_puts (out
, level
+ 1, "</rule>");
146 xml_puts (out
, level
, "</itemset>");
150 /*-----------------------------------------------------------.
151 | Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on |
153 `-----------------------------------------------------------*/
156 print_transitions (state
*s
, FILE *out
, int level
)
158 transitions
*trans
= s
->transitions
;
162 for (i
= 0; i
< trans
->num
; i
++)
163 if (!TRANSITION_IS_DISABLED (trans
, i
))
168 /* Nothing to report. */
170 xml_puts (out
, level
, "<transitions/>");
174 /* Report lookahead tokens and shifts. */
175 xml_puts (out
, level
, "<transitions>");
177 for (i
= 0; i
< trans
->num
; i
++)
178 if (!TRANSITION_IS_DISABLED (trans
, i
)
179 && TRANSITION_IS_SHIFT (trans
, i
))
181 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
182 char const *tag
= sym
->tag
;
183 state
*s1
= trans
->states
[i
];
185 xml_printf (out
, level
+ 1,
186 "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>",
187 xml_escape (tag
), s1
->number
);
190 for (i
= 0; i
< trans
->num
; i
++)
191 if (!TRANSITION_IS_DISABLED (trans
, i
)
192 && !TRANSITION_IS_SHIFT (trans
, i
))
194 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
195 char const *tag
= sym
->tag
;
196 state
*s1
= trans
->states
[i
];
198 xml_printf (out
, level
+ 1,
199 "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>",
200 xml_escape (tag
), s1
->number
);
203 xml_puts (out
, level
, "</transitions>");
207 /*--------------------------------------------------------.
208 | Report the explicit errors of S raised from %nonassoc. |
209 `--------------------------------------------------------*/
212 print_errs (FILE *out
, int level
, state
*s
)
214 errs
*errp
= s
->errs
;
218 for (i
= 0; i
< errp
->num
; ++i
)
219 if (errp
->symbols
[i
])
222 /* Nothing to report. */
224 xml_puts (out
, level
, "<errors/>");
228 /* Report lookahead tokens and errors. */
229 xml_puts (out
, level
, "<errors>");
230 for (i
= 0; i
< errp
->num
; ++i
)
231 if (errp
->symbols
[i
])
233 char const *tag
= errp
->symbols
[i
]->tag
;
234 xml_printf (out
, level
+ 1,
235 "<error symbol=\"%s\">nonassociative</error>",
238 xml_puts (out
, level
, "</errors>");
242 /*-------------------------------------------------------------------------.
243 | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default'). |
244 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
246 `-------------------------------------------------------------------------*/
249 print_reduction (FILE *out
, int level
, char const *lookahead_token
,
250 rule
*r
, bool enabled
)
253 xml_printf (out
, level
,
254 "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
255 xml_escape (lookahead_token
),
257 enabled
? "true" : "false");
259 xml_printf (out
, level
,
260 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
261 xml_escape (lookahead_token
),
262 enabled
? "true" : "false");
266 /*-------------------------------------------.
267 | Report on OUT the reduction actions of S. |
268 `-------------------------------------------*/
271 print_reductions (FILE *out
, int level
, state
*s
)
273 transitions
*trans
= s
->transitions
;
274 reductions
*reds
= s
->reductions
;
275 rule
*default_rule
= NULL
;
279 if (reds
->num
== 0) {
280 xml_puts (out
, level
, "<reductions/>");
284 if (yydefact
[s
->number
] != 0)
285 default_rule
= &rules
[yydefact
[s
->number
] - 1];
287 bitset_zero (no_reduce_set
);
288 FOR_EACH_SHIFT (trans
, i
)
289 bitset_set (no_reduce_set
, TRANSITION_SYMBOL (trans
, i
));
290 for (i
= 0; i
< s
->errs
->num
; ++i
)
291 if (s
->errs
->symbols
[i
])
292 bitset_set (no_reduce_set
, s
->errs
->symbols
[i
]->number
);
297 if (reds
->lookahead_tokens
)
298 for (i
= 0; i
< ntokens
; i
++)
300 bool count
= bitset_test (no_reduce_set
, i
);
302 for (j
= 0; j
< reds
->num
; ++j
)
303 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
307 if (reds
->rules
[j
] != default_rule
)
318 /* Nothing to report. */
320 xml_puts (out
, level
, "<reductions/>");
324 xml_puts (out
, level
, "<reductions>");
326 /* Report lookahead tokens (or $default) and reductions. */
327 if (reds
->lookahead_tokens
)
328 for (i
= 0; i
< ntokens
; i
++)
330 bool defaulted
= false;
331 bool count
= bitset_test (no_reduce_set
, i
);
333 for (j
= 0; j
< reds
->num
; ++j
)
334 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
338 if (reds
->rules
[j
] != default_rule
)
339 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
340 reds
->rules
[j
], true);
348 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
351 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
352 reds
->rules
[j
], false);
358 print_reduction (out
, level
+ 1,
359 "$default", default_rule
, true);
361 xml_puts (out
, level
, "</reductions>");
365 /*--------------------------------------------------------------.
366 | Report on OUT all the actions (shifts, gotos, reductions, and |
367 | explicit erros from %nonassoc) of S. |
368 `--------------------------------------------------------------*/
371 print_actions (FILE *out
, int level
, state
*s
)
373 xml_puts (out
, level
, "<actions>");
374 print_transitions (s
, out
, level
+ 1);
375 print_errs (out
, level
+ 1, s
);
376 print_reductions (out
, level
+ 1, s
);
377 xml_puts (out
, level
, "</actions>");
381 /*----------------------------------.
382 | Report all the data on S on OUT. |
383 `----------------------------------*/
386 print_state (FILE *out
, int level
, state
*s
)
389 xml_printf (out
, level
, "<state number=\"%d\">", s
->number
);
390 print_core (out
, level
+ 1, s
);
391 print_actions (out
, level
+ 1, s
);
392 if ((report_flag
& report_solved_conflicts
) && s
->solved_conflicts_xml
)
394 xml_puts (out
, level
+ 1, "<solved-conflicts>");
395 fputs (s
->solved_conflicts_xml
, out
);
396 xml_puts (out
, level
+ 1, "</solved-conflicts>");
399 xml_puts (out
, level
+ 1, "<solved-conflicts/>");
400 xml_puts (out
, level
, "</state>");
404 /*-----------------------------------------.
405 | Print information on the whole grammar. |
406 `-----------------------------------------*/
409 print_grammar (FILE *out
, int level
)
414 xml_puts (out
, level
, "<grammar>");
415 grammar_rules_print_xml (out
, level
);
418 xml_puts (out
, level
+ 1, "<terminals>");
419 for (i
= 0; i
< max_user_token_number
+ 1; i
++)
420 if (token_translations
[i
] != undeftoken
->number
)
422 char const *tag
= symbols
[token_translations
[i
]]->tag
;
426 xml_printf (out
, level
+ 2,
427 "<terminal type=\"%d\" symbol=\"%s\">",
428 i
, xml_escape (tag
));
430 for (r
= 0; r
< nrules
; r
++)
431 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
432 if (item_number_as_symbol_number (*rhsp
) == token_translations
[i
])
434 xml_printf (out
, level
+ 3, "<rule>%d</rule>", r
);
437 xml_puts (out
, level
+ 2, "</terminal>");
439 xml_puts (out
, level
+ 1, "</terminals>");
442 xml_puts (out
, level
+ 1, "<nonterminals>");
443 for (i
= ntokens
; i
< nsyms
; i
++)
445 int left_count
= 0, right_count
= 0;
447 char const *tag
= symbols
[i
]->tag
;
449 for (r
= 0; r
< nrules
; r
++)
452 if (rules
[r
].lhs
->number
== i
)
454 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
455 if (item_number_as_symbol_number (*rhsp
) == i
)
462 xml_printf (out
, level
+ 2,
463 "<nonterminal type=\"%d\" symbol=\"%s\">",
464 i
, xml_escape (tag
));
468 xml_puts (out
, level
+ 3, "<left>");
469 for (r
= 0; r
< nrules
; r
++)
471 if (rules
[r
].lhs
->number
== i
)
472 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
474 xml_puts (out
, level
+ 3, "</left>");
479 xml_puts (out
, level
+ 3, "<right>");
480 for (r
= 0; r
< nrules
; r
++)
483 for (rhsp
= rules
[r
].rhs
; *rhsp
>= 0; rhsp
++)
484 if (item_number_as_symbol_number (*rhsp
) == i
)
486 xml_printf (out
, level
+ 4, "<rule>%d</rule>", r
);
490 xml_puts (out
, level
+ 3, "</right>");
493 xml_puts (out
, level
+ 2, "</nonterminal>");
495 xml_puts (out
, level
+ 1, "</nonterminals>");
496 xml_puts (out
, level
, "</grammar>");
500 xml_puts (FILE *out
, int level
, char const *s
)
503 for (i
= 0; i
< level
; i
++)
510 xml_printf (FILE *out
, int level
, char const *fmt
, ...)
515 for (i
= 0; i
< level
; i
++)
518 va_start (arglist
, fmt
);
519 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 return xml_escape_string (escape_bufs
+ n
, str
);
560 xml_escape (char const *str
)
562 return xml_escape_n (0, str
);
571 FILE *out
= xfopen (spec_xml_file
, "w");
573 fputs ("<?xml version=\"1.0\"?>\n\n", out
);
574 xml_printf (out
, level
, "<bison-xml-report version=\"%s\">",
575 xml_escape (VERSION
));
578 xml_printf (out
, level
+ 1, "<filename>%s</filename>",
579 xml_escape (grammar_file
));
581 /* print reductions */
582 reduce_xml (out
, level
+ 1);
584 /* print rules never reduced */
585 print_rules_never_reduced (out
, level
+ 1);
587 /* print conflicts */
588 conflicts_output_xml (out
, level
+ 1);
591 print_grammar (out
, level
+ 1);
593 if (report_flag
& report_itemsets
)
594 new_closure (nritems
);
595 no_reduce_set
= bitset_create (ntokens
, BITSET_FIXED
);
597 /* print automaton */
599 xml_puts (out
, level
+ 1, "<automaton>");
600 for (i
= 0; i
< nstates
; i
++)
601 print_state (out
, level
+ 2, states
[i
]);
602 xml_puts (out
, level
+ 1, "</automaton>");
604 bitset_free (no_reduce_set
);
605 if (report_flag
& report_itemsets
)
608 xml_puts (out
, 0, "</bison-xml-report>");
610 free (escape_bufs
[0].ptr
);
611 free (escape_bufs
[1].ptr
);