]>
git.saurik.com Git - bison.git/blob - src/print-xml.c
cbe71a161c4ef8106ba814560a9ada2591a05f7f
   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 type=\"%d\" symbol=\"%s\">", 
 433                     i
, xml_escape (tag
)); 
 435         for (r 
= 0; r 
< nrules
; r
++) 
 436           for (rhsp 
= rules
[r
].rhs
; *rhsp 
>= 0; rhsp
++) 
 437             if (item_number_as_symbol_number (*rhsp
) == token_translations
[i
]) 
 439                 xml_printf (out
, level 
+ 3, "<rule>%d</rule>", r
); 
 442         xml_puts (out
, level 
+ 2, "</terminal>"); 
 444   xml_puts (out
, level 
+ 1, "</terminals>"); 
 447   xml_puts (out
, level 
+ 1, "<nonterminals>"); 
 448   for (i 
= ntokens
; i 
< nsyms
; i
++) 
 450       int left_count 
= 0, right_count 
= 0; 
 452       char const *tag 
= symbols
[i
]->tag
; 
 454       for (r 
= 0; r 
< nrules
; r
++) 
 457           if (rules
[r
].lhs
->number 
== i
) 
 459           for (rhsp 
= rules
[r
].rhs
; *rhsp 
>= 0; rhsp
++) 
 460             if (item_number_as_symbol_number (*rhsp
) == i
) 
 467       xml_printf (out
, level 
+ 2, 
 468                   "<nonterminal type=\"%d\" symbol=\"%s\">", 
 469                   i
, xml_escape (tag
)); 
 473           xml_puts (out
, level 
+ 3, "<left>"); 
 474           for (r 
= 0; r 
< nrules
; r
++) 
 476               if (rules
[r
].lhs
->number 
== i
) 
 477                 xml_printf (out
, level 
+ 4, "<rule>%d</rule>", r
); 
 479           xml_puts (out
, level 
+ 3, "</left>"); 
 484           xml_puts (out
, level 
+ 3, "<right>"); 
 485           for (r 
= 0; r 
< nrules
; r
++) 
 488               for (rhsp 
= rules
[r
].rhs
; *rhsp 
>= 0; rhsp
++) 
 489                 if (item_number_as_symbol_number (*rhsp
) == i
) 
 491                     xml_printf (out
, level 
+ 4, "<rule>%d</rule>", r
); 
 495           xml_puts (out
, level 
+ 3, "</right>"); 
 498       xml_puts (out
, level 
+ 2, "</nonterminal>"); 
 500   xml_puts (out
, level 
+ 1, "</nonterminals>"); 
 501   xml_puts (out
, level
, "</grammar>"); 
 505 xml_puts (FILE *out
, int level
, char const *s
) 
 508   for (i 
= 0; i 
< level
; i
++) 
 515 xml_printf (FILE *out
, int level
, char const *fmt
, ...) 
 520   for (i 
= 0; i 
< level
; i
++) 
 523   va_start (arglist
, fmt
); 
 524   vfprintf (out
, fmt
, arglist
); 
 531 xml_escape_string (struct escape_buf 
*buf
, char const *str
) 
 533   size_t len 
= strlen (str
); 
 534   size_t max_expansion 
= sizeof """ - 1; 
 537   if (buf
->size 
<= max_expansion 
* len
) 
 539       buf
->size 
= max_expansion 
* len 
+ 1; 
 540       buf
->ptr 
= x2realloc (buf
->ptr
, &buf
->size
); 
 547       default: *p
++ = *str
; break; 
 548       case '&': p 
= stpcpy (p
, "&" ); break; 
 549       case '<': p 
= stpcpy (p
, "<"  ); break; 
 550       case '>': p 
= stpcpy (p
, ">"  ); break; 
 551       case '"': p 
= stpcpy (p
, """); break; 
 559 xml_escape_n (int n
, char const *str
) 
 561   return xml_escape_string (escape_bufs 
+ n
, str
); 
 565 xml_escape (char const *str
) 
 567   return xml_escape_n (0, str
); 
 576   FILE *out 
= xfopen (spec_xml_file
, "w"); 
 578   fputs ("<?xml version=\"1.0\"?>\n\n", out
); 
 579   xml_printf (out
, level
, "<bison-xml-report version=\"%s\">", 
 580               xml_escape (VERSION
)); 
 583   xml_printf (out
, level 
+ 1, "<filename>%s</filename>", 
 584               xml_escape (grammar_file
)); 
 586   /* print reductions */ 
 587   reduce_xml (out
, level 
+ 1); 
 589   /* print rules never reduced */ 
 590   print_rules_never_reduced (out
, level 
+ 1); 
 593   print_grammar (out
, level 
+ 1); 
 595   if (report_flag 
& report_itemsets
) 
 596     new_closure (nritems
); 
 597   no_reduce_set 
=  bitset_create (ntokens
, BITSET_FIXED
); 
 599   /* print automaton */ 
 601   xml_puts (out
, level 
+ 1, "<automaton>"); 
 602   for (i 
= 0; i 
< nstates
; i
++) 
 603     print_state (out
, level 
+ 2, states
[i
]); 
 604   xml_puts (out
, level 
+ 1, "</automaton>"); 
 606   bitset_free (no_reduce_set
); 
 607   if (report_flag 
& report_itemsets
) 
 610   xml_puts (out
, 0, "</bison-xml-report>"); 
 612   free (escape_bufs
[0].ptr
); 
 613   free (escape_bufs
[1].ptr
);