]>
git.saurik.com Git - bison.git/blob - src/print-xml.c
1 /* Print an xml on generated parser, for Bison,
3 Copyright (C) 2007, 2009-2015 Free Software Foundation, Inc.
5 This file is part of Bison, the GNU Compiler Compiler.
7 This program 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 3 of the License, or
10 (at your option) any later version.
12 This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
29 #include "conflicts.h"
35 #include "print-xml.h"
42 static bitset no_reduce_set
;
48 enum { num_escape_bufs
= 3 };
49 static struct escape_buf escape_bufs
[num_escape_bufs
];
52 /*--------------------------------.
53 | Report information on a state. |
54 `--------------------------------*/
57 print_core (FILE *out
, int level
, state
*s
)
60 item_number
*sitems
= s
->items
;
61 size_t snritems
= s
->nitems
;
63 /* Output all the items of a state, not only its kernel. */
64 closure (sitems
, snritems
);
70 xml_puts (out
, level
, "<itemset/>");
74 xml_puts (out
, level
, "<itemset>");
76 for (i
= 0; i
< snritems
; i
++)
79 item_number
*sp1
= ritem
+ sitems
[i
];
80 item_number
*sp
= sp1
;
86 r
= &rules
[item_number_as_rule_number (*sp
)];
89 /* Display the lookahead tokens? */
90 if (item_number_is_rule_number (*sp1
))
92 reductions
*reds
= s
->reductions
;
93 int red
= state_reduction_find (s
, r
);
94 /* Print item with lookaheads if there are. */
95 if (reds
->lookahead_tokens
&& red
!= -1)
97 xml_printf (out
, level
+ 1,
98 "<item rule-number=\"%d\" point=\"%d\">",
100 state_rule_lookahead_tokens_print_xml (s
, r
,
102 xml_puts (out
, level
+ 1, "</item>");
108 xml_printf (out
, level
+ 1,
109 "<item rule-number=\"%d\" point=\"%d\"/>",
113 xml_puts (out
, level
, "</itemset>");
117 /*-----------------------------------------------------------.
118 | Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on |
120 `-----------------------------------------------------------*/
123 print_transitions (state
*s
, FILE *out
, int level
)
125 transitions
*trans
= s
->transitions
;
129 for (i
= 0; i
< trans
->num
; i
++)
130 if (!TRANSITION_IS_DISABLED (trans
, i
))
135 /* Nothing to report. */
138 xml_puts (out
, level
, "<transitions/>");
142 /* Report lookahead tokens and shifts. */
143 xml_puts (out
, level
, "<transitions>");
145 for (i
= 0; i
< trans
->num
; i
++)
146 if (!TRANSITION_IS_DISABLED (trans
, i
)
147 && TRANSITION_IS_SHIFT (trans
, i
))
149 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
150 char const *tag
= sym
->tag
;
151 state
*s1
= trans
->states
[i
];
153 xml_printf (out
, level
+ 1,
154 "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>",
155 xml_escape (tag
), s1
->number
);
158 for (i
= 0; i
< trans
->num
; i
++)
159 if (!TRANSITION_IS_DISABLED (trans
, i
)
160 && !TRANSITION_IS_SHIFT (trans
, i
))
162 symbol
*sym
= symbols
[TRANSITION_SYMBOL (trans
, i
)];
163 char const *tag
= sym
->tag
;
164 state
*s1
= trans
->states
[i
];
166 xml_printf (out
, level
+ 1,
167 "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>",
168 xml_escape (tag
), s1
->number
);
171 xml_puts (out
, level
, "</transitions>");
175 /*--------------------------------------------------------.
176 | Report the explicit errors of S raised from %nonassoc. |
177 `--------------------------------------------------------*/
180 print_errs (FILE *out
, int level
, state
*s
)
182 errs
*errp
= s
->errs
;
186 for (i
= 0; i
< errp
->num
; ++i
)
187 if (errp
->symbols
[i
])
190 /* Nothing to report. */
193 xml_puts (out
, level
, "<errors/>");
197 /* Report lookahead tokens and errors. */
198 xml_puts (out
, level
, "<errors>");
199 for (i
= 0; i
< errp
->num
; ++i
)
200 if (errp
->symbols
[i
])
202 char const *tag
= errp
->symbols
[i
]->tag
;
203 xml_printf (out
, level
+ 1,
204 "<error symbol=\"%s\">nonassociative</error>",
207 xml_puts (out
, level
, "</errors>");
211 /*-------------------------------------------------------------------------.
212 | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be 'default'). |
213 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and |
215 `-------------------------------------------------------------------------*/
218 print_reduction (FILE *out
, int level
, char const *lookahead_token
,
219 rule
*r
, bool enabled
)
222 xml_printf (out
, level
,
223 "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>",
224 xml_escape (lookahead_token
),
226 enabled
? "true" : "false");
228 xml_printf (out
, level
,
229 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>",
230 xml_escape (lookahead_token
),
231 enabled
? "true" : "false");
235 /*-------------------------------------------.
236 | Report on OUT the reduction actions of S. |
237 `-------------------------------------------*/
240 print_reductions (FILE *out
, int level
, state
*s
)
242 transitions
*trans
= s
->transitions
;
243 reductions
*reds
= s
->reductions
;
244 rule
*default_reduction
= NULL
;
250 xml_puts (out
, level
, "<reductions/>");
254 if (yydefact
[s
->number
] != 0)
255 default_reduction
= &rules
[yydefact
[s
->number
] - 1];
257 bitset_zero (no_reduce_set
);
258 FOR_EACH_SHIFT (trans
, i
)
259 bitset_set (no_reduce_set
, TRANSITION_SYMBOL (trans
, i
));
260 for (i
= 0; i
< s
->errs
->num
; ++i
)
261 if (s
->errs
->symbols
[i
])
262 bitset_set (no_reduce_set
, s
->errs
->symbols
[i
]->number
);
264 if (default_reduction
)
267 if (reds
->lookahead_tokens
)
268 for (i
= 0; i
< ntokens
; i
++)
270 bool count
= bitset_test (no_reduce_set
, i
);
272 for (j
= 0; j
< reds
->num
; ++j
)
273 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
277 if (reds
->rules
[j
] != default_reduction
)
288 /* Nothing to report. */
291 xml_puts (out
, level
, "<reductions/>");
295 xml_puts (out
, level
, "<reductions>");
297 /* Report lookahead tokens (or $default) and reductions. */
298 if (reds
->lookahead_tokens
)
299 for (i
= 0; i
< ntokens
; i
++)
301 bool defaulted
= false;
302 bool count
= bitset_test (no_reduce_set
, i
);
304 for (j
= 0; j
< reds
->num
; ++j
)
305 if (bitset_test (reds
->lookahead_tokens
[j
], i
))
309 if (reds
->rules
[j
] != default_reduction
)
310 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
311 reds
->rules
[j
], true);
319 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
320 default_reduction
, true);
322 print_reduction (out
, level
+ 1, symbols
[i
]->tag
,
323 reds
->rules
[j
], false);
328 if (default_reduction
)
329 print_reduction (out
, level
+ 1,
330 "$default", default_reduction
, true);
332 xml_puts (out
, level
, "</reductions>");
336 /*--------------------------------------------------------------.
337 | Report on OUT all the actions (shifts, gotos, reductions, and |
338 | explicit erros from %nonassoc) of S. |
339 `--------------------------------------------------------------*/
342 print_actions (FILE *out
, int level
, state
*s
)
344 xml_puts (out
, level
, "<actions>");
345 print_transitions (s
, out
, level
+ 1);
346 print_errs (out
, level
+ 1, s
);
347 print_reductions (out
, level
+ 1, s
);
348 xml_puts (out
, level
, "</actions>");
352 /*----------------------------------.
353 | Report all the data on S on OUT. |
354 `----------------------------------*/
357 print_state (FILE *out
, int level
, state
*s
)
360 xml_printf (out
, level
, "<state number=\"%d\">", s
->number
);
361 print_core (out
, level
+ 1, s
);
362 print_actions (out
, level
+ 1, s
);
363 if (s
->solved_conflicts_xml
)
365 xml_puts (out
, level
+ 1, "<solved-conflicts>");
366 fputs (s
->solved_conflicts_xml
, out
);
367 xml_puts (out
, level
+ 1, "</solved-conflicts>");
370 xml_puts (out
, level
+ 1, "<solved-conflicts/>");
371 xml_puts (out
, level
, "</state>");
375 /*-----------------------------------------.
376 | Print information on the whole grammar. |
377 `-----------------------------------------*/
380 print_grammar (FILE *out
, int level
)
385 xml_puts (out
, level
, "<grammar>");
386 grammar_rules_print_xml (out
, level
);
389 xml_puts (out
, level
+ 1, "<terminals>");
390 for (i
= 0; i
< max_user_token_number
+ 1; i
++)
391 if (token_translations
[i
] != undeftoken
->number
)
393 char const *tag
= symbols
[token_translations
[i
]]->tag
;
394 int precedence
= symbols
[token_translations
[i
]]->prec
;
395 assoc associativity
= symbols
[token_translations
[i
]]->assoc
;
396 xml_indent (out
, level
+ 2);
398 "<terminal symbol-number=\"%d\" token-number=\"%d\""
399 " name=\"%s\" usefulness=\"%s\"",
400 token_translations
[i
], i
, xml_escape (tag
),
401 reduce_token_unused_in_grammar (token_translations
[i
])
402 ? "unused-in-grammar" : "useful");
404 fprintf (out
, " prec=\"%d\"", precedence
);
405 if (associativity
!= undef_assoc
)
406 fprintf (out
, " assoc=\"%s\"", assoc_to_string (associativity
) + 1);
409 xml_puts (out
, level
+ 1, "</terminals>");
412 xml_puts (out
, level
+ 1, "<nonterminals>");
413 for (i
= ntokens
; i
< nsyms
+ nuseless_nonterminals
; i
++)
415 char const *tag
= symbols
[i
]->tag
;
416 xml_printf (out
, level
+ 2,
417 "<nonterminal symbol-number=\"%d\" name=\"%s\""
418 " usefulness=\"%s\"/>",
420 reduce_nonterminal_useless_in_grammar (i
)
421 ? "useless-in-grammar" : "useful");
423 xml_puts (out
, level
+ 1, "</nonterminals>");
424 xml_puts (out
, level
, "</grammar>");
428 xml_indent (FILE *out
, int level
)
431 for (i
= 0; i
< level
; i
++)
436 xml_puts (FILE *out
, int level
, char const *s
)
438 xml_indent (out
, level
);
444 xml_printf (FILE *out
, int level
, char const *fmt
, ...)
448 xml_indent (out
, level
);
450 va_start (arglist
, fmt
);
451 vfprintf (out
, fmt
, arglist
);
458 xml_escape_string (struct escape_buf
*buf
, char const *str
)
460 size_t len
= strlen (str
);
461 size_t max_expansion
= sizeof """ - 1;
464 if (buf
->size
<= max_expansion
* len
)
466 buf
->size
= max_expansion
* len
+ 1;
467 buf
->ptr
= x2realloc (buf
->ptr
, &buf
->size
);
474 default: *p
++ = *str
; break;
475 case '&': p
= stpcpy (p
, "&" ); break;
476 case '<': p
= stpcpy (p
, "<" ); break;
477 case '>': p
= stpcpy (p
, ">" ); break;
478 case '"': p
= stpcpy (p
, """); break;
486 xml_escape_n (int n
, char const *str
)
488 return xml_escape_string (escape_bufs
+ n
, str
);
492 xml_escape (char const *str
)
494 return xml_escape_n (0, str
);
502 FILE *out
= xfopen (spec_xml_file
, "w");
504 fputs ("<?xml version=\"1.0\"?>\n\n", out
);
505 xml_printf (out
, level
,
506 "<bison-xml-report version=\"%s\" bug-report=\"%s\""
508 xml_escape_n (0, VERSION
),
509 xml_escape_n (1, PACKAGE_BUGREPORT
),
510 xml_escape_n (2, PACKAGE_URL
));
513 xml_printf (out
, level
+ 1, "<filename>%s</filename>",
514 xml_escape (grammar_file
));
517 print_grammar (out
, level
+ 1);
519 new_closure (nritems
);
520 no_reduce_set
= bitset_create (ntokens
, BITSET_FIXED
);
522 /* print automaton */
524 xml_puts (out
, level
+ 1, "<automaton>");
527 for (i
= 0; i
< nstates
; i
++)
528 print_state (out
, level
+ 2, states
[i
]);
530 xml_puts (out
, level
+ 1, "</automaton>");
532 bitset_free (no_reduce_set
);
535 xml_puts (out
, 0, "</bison-xml-report>");
539 for (i
= 0; i
< num_escape_bufs
; ++i
)
540 free (escape_bufs
[i
].ptr
);