]>
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-2010 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 | Report information on a state.  | 
  56 `--------------------------------*/ 
  59 print_core (FILE *out
, int level
, state 
*s
) 
  62   item_number 
*sitems 
= s
->items
; 
  63   size_t snritems 
= s
->nitems
; 
  65   /* Output all the items of a state, not only its kernel.  */ 
  66   closure (sitems
, snritems
); 
  71     xml_puts (out
, level
, "<itemset/>"); 
  75   xml_puts (out
, level
, "<itemset>"); 
  77   for (i 
= 0; i 
< snritems
; i
++) 
  84       sp1 
= sp 
= ritem 
+ sitems
[i
]; 
  89       r 
= item_number_as_rule_number (*sp
); 
  92       /* Display the lookahead tokens?  */ 
  93       if (item_number_is_rule_number (*sp1
)) 
  95           reductions 
*reds 
= s
->reductions
; 
  96           int red 
= state_reduction_find (s
, &rules
[r
]); 
  97           /* Print item with lookaheads if there are. */ 
  98           if (reds
->lookahead_tokens 
&& red 
!= -1) 
 100               xml_printf (out
, level 
+ 1, 
 101                           "<item rule-number=\"%d\" point=\"%d\">", 
 102                           rules
[r
].number
, sp1 
- sp
); 
 103               state_rule_lookahead_tokens_print_xml (s
, &rules
[r
], 
 105               xml_puts (out
, level 
+ 1, "</item>"); 
 112           xml_printf (out
, level 
+ 1, 
 113                       "<item rule-number=\"%d\" point=\"%d\"/>", 
 118   xml_puts (out
, level
, "</itemset>"); 
 122 /*-----------------------------------------------------------. 
 123 | Report the shifts if DISPLAY_SHIFTS_P or the gotos of S on | 
 125 `-----------------------------------------------------------*/ 
 128 print_transitions (state 
*s
, FILE *out
, int level
) 
 130   transitions 
*trans 
= s
->transitions
; 
 134   for (i 
= 0; i 
< trans
->num
; i
++) 
 135     if (!TRANSITION_IS_DISABLED (trans
, i
)) 
 140   /* Nothing to report. */ 
 142     xml_puts (out
, level
, "<transitions/>"); 
 146   /* Report lookahead tokens and shifts.  */ 
 147   xml_puts (out
, level
, "<transitions>"); 
 149   for (i 
= 0; i 
< trans
->num
; i
++) 
 150     if (!TRANSITION_IS_DISABLED (trans
, i
) 
 151         && TRANSITION_IS_SHIFT (trans
, i
)) 
 153         symbol 
*sym 
= symbols
[TRANSITION_SYMBOL (trans
, i
)]; 
 154         char const *tag 
= sym
->tag
; 
 155         state 
*s1 
= trans
->states
[i
]; 
 157         xml_printf (out
, level 
+ 1, 
 158                     "<transition type=\"shift\" symbol=\"%s\" state=\"%d\"/>", 
 159                     xml_escape (tag
), s1
->number
); 
 162   for (i 
= 0; i 
< trans
->num
; i
++) 
 163     if (!TRANSITION_IS_DISABLED (trans
, i
) 
 164         && !TRANSITION_IS_SHIFT (trans
, i
)) 
 166         symbol 
*sym 
= symbols
[TRANSITION_SYMBOL (trans
, i
)]; 
 167         char const *tag 
= sym
->tag
; 
 168         state 
*s1 
= trans
->states
[i
]; 
 170         xml_printf (out
, level 
+ 1, 
 171                     "<transition type=\"goto\" symbol=\"%s\" state=\"%d\"/>", 
 172                     xml_escape (tag
), s1
->number
); 
 175   xml_puts (out
, level
, "</transitions>"); 
 179 /*--------------------------------------------------------. 
 180 | Report the explicit errors of S raised from %nonassoc.  | 
 181 `--------------------------------------------------------*/ 
 184 print_errs (FILE *out
, int level
, state 
*s
) 
 186   errs 
*errp 
= s
->errs
; 
 190   for (i 
= 0; i 
< errp
->num
; ++i
) 
 191     if (errp
->symbols
[i
]) 
 194   /* Nothing to report. */ 
 196     xml_puts (out
, level
, "<errors/>"); 
 200   /* Report lookahead tokens and errors.  */ 
 201   xml_puts (out
, level
, "<errors>"); 
 202   for (i 
= 0; i 
< errp
->num
; ++i
) 
 203     if (errp
->symbols
[i
]) 
 205         char const *tag 
= errp
->symbols
[i
]->tag
; 
 206         xml_printf (out
, level 
+ 1, 
 207                     "<error symbol=\"%s\">nonassociative</error>", 
 210   xml_puts (out
, level
, "</errors>"); 
 214 /*-------------------------------------------------------------------------. 
 215 | Report a reduction of RULE on LOOKAHEAD_TOKEN (which can be `default').  | 
 216 | If not ENABLED, the rule is masked by a shift or a reduce (S/R and       | 
 218 `-------------------------------------------------------------------------*/ 
 221 print_reduction (FILE *out
, int level
, char const *lookahead_token
, 
 222                  rule 
*r
, bool enabled
) 
 225     xml_printf (out
, level
, 
 226                 "<reduction symbol=\"%s\" rule=\"%d\" enabled=\"%s\"/>", 
 227                 xml_escape (lookahead_token
), 
 229                 enabled 
? "true" : "false"); 
 231     xml_printf (out
, level
, 
 232                 "<reduction symbol=\"%s\" rule=\"accept\" enabled=\"%s\"/>", 
 233                 xml_escape (lookahead_token
), 
 234                 enabled 
? "true" : "false"); 
 238 /*-------------------------------------------. 
 239 | Report on OUT the reduction actions of S.  | 
 240 `-------------------------------------------*/ 
 243 print_reductions (FILE *out
, int level
, state 
*s
) 
 245   transitions 
*trans 
= s
->transitions
; 
 246   reductions 
*reds 
= s
->reductions
; 
 247   rule 
*default_reduction 
= NULL
; 
 253       xml_puts (out
, level
, "<reductions/>"); 
 257   if (yydefact
[s
->number
] != 0) 
 258     default_reduction 
= &rules
[yydefact
[s
->number
] - 1]; 
 260   bitset_zero (no_reduce_set
); 
 261   FOR_EACH_SHIFT (trans
, i
) 
 262     bitset_set (no_reduce_set
, TRANSITION_SYMBOL (trans
, i
)); 
 263   for (i 
= 0; i 
< s
->errs
->num
; ++i
) 
 264     if (s
->errs
->symbols
[i
]) 
 265       bitset_set (no_reduce_set
, s
->errs
->symbols
[i
]->number
); 
 267   if (default_reduction
) 
 270   if (reds
->lookahead_tokens
) 
 271     for (i 
= 0; i 
< ntokens
; i
++) 
 273         bool count 
= bitset_test (no_reduce_set
, i
); 
 275         for (j 
= 0; j 
< reds
->num
; ++j
) 
 276           if (bitset_test (reds
->lookahead_tokens
[j
], i
)) 
 280                   if (reds
->rules
[j
] != default_reduction
) 
 291   /* Nothing to report. */ 
 293     xml_puts (out
, level
, "<reductions/>"); 
 297   xml_puts (out
, level
, "<reductions>"); 
 299   /* Report lookahead tokens (or $default) and reductions.  */ 
 300   if (reds
->lookahead_tokens
) 
 301     for (i 
= 0; i 
< ntokens
; i
++) 
 303         bool defaulted 
= false; 
 304         bool count 
= bitset_test (no_reduce_set
, i
); 
 306         for (j 
= 0; j 
< reds
->num
; ++j
) 
 307           if (bitset_test (reds
->lookahead_tokens
[j
], i
)) 
 311                   if (reds
->rules
[j
] != default_reduction
) 
 312                     print_reduction (out
, level 
+ 1, symbols
[i
]->tag
, 
 313                                      reds
->rules
[j
], true); 
 321                     print_reduction (out
, level 
+ 1, symbols
[i
]->tag
, 
 322                                      default_reduction
, true); 
 324                   print_reduction (out
, level 
+ 1, symbols
[i
]->tag
, 
 325                                    reds
->rules
[j
], false); 
 330   if (default_reduction
) 
 331     print_reduction (out
, level 
+ 1, 
 332                      "$default", default_reduction
, true); 
 334   xml_puts (out
, level
, "</reductions>"); 
 338 /*--------------------------------------------------------------. 
 339 | Report on OUT all the actions (shifts, gotos, reductions, and | 
 340 | explicit erros from %nonassoc) of S.                          | 
 341 `--------------------------------------------------------------*/ 
 344 print_actions (FILE *out
, int level
, state 
*s
) 
 346   xml_puts (out
, level
, "<actions>"); 
 347   print_transitions (s
, out
, level 
+ 1); 
 348   print_errs (out
, level 
+ 1, s
); 
 349   print_reductions (out
, level 
+ 1, s
); 
 350   xml_puts (out
, level
, "</actions>"); 
 354 /*----------------------------------. 
 355 | Report all the data on S on OUT.  | 
 356 `----------------------------------*/ 
 359 print_state (FILE *out
, int level
, state 
*s
) 
 362   xml_printf (out
, level
, "<state number=\"%d\">", s
->number
); 
 363   print_core (out
, level 
+ 1, s
); 
 364   print_actions (out
, level 
+ 1, s
); 
 365   if (s
->solved_conflicts_xml
) 
 367       xml_puts (out
, level 
+ 1, "<solved-conflicts>"); 
 368       fputs (s
->solved_conflicts_xml
, out
); 
 369       xml_puts (out
, level 
+ 1, "</solved-conflicts>"); 
 372     xml_puts (out
, level 
+ 1, "<solved-conflicts/>"); 
 373   xml_puts (out
, level
, "</state>"); 
 377 /*-----------------------------------------. 
 378 | Print information on the whole grammar.  | 
 379 `-----------------------------------------*/ 
 382 print_grammar (FILE *out
, int level
) 
 387   xml_puts (out
, level
, "<grammar>"); 
 388   grammar_rules_print_xml (out
, level
); 
 391   xml_puts (out
, level 
+ 1, "<terminals>"); 
 392   for (i 
= 0; i 
< max_user_token_number 
+ 1; i
++) 
 393     if (token_translations
[i
] != undeftoken
->number
) 
 395         char const *tag 
= symbols
[token_translations
[i
]]->tag
; 
 396         int precedence 
= symbols
[token_translations
[i
]]->prec
; 
 397         assoc associativity 
= symbols
[token_translations
[i
]]->assoc
; 
 398         xml_indent (out
, level 
+ 2); 
 400                  "<terminal symbol-number=\"%d\" token-number=\"%d\"" 
 401                  " name=\"%s\" usefulness=\"%s\"", 
 402                  token_translations
[i
], i
, xml_escape (tag
), 
 403                  reduce_token_unused_in_grammar (token_translations
[i
]) 
 404                    ? "unused-in-grammar" : "useful"); 
 406           fprintf (out
, " prec=\"%d\"", precedence
); 
 407         if (associativity 
!= undef_assoc
) 
 408           fprintf (out
, " assoc=\"%s\"", assoc_to_string (associativity
) + 1); 
 411   xml_puts (out
, level 
+ 1, "</terminals>"); 
 414   xml_puts (out
, level 
+ 1, "<nonterminals>"); 
 415   for (i 
= ntokens
; i 
< nsyms 
+ nuseless_nonterminals
; i
++) 
 417       char const *tag 
= symbols
[i
]->tag
; 
 418       xml_printf (out
, level 
+ 2, 
 419                   "<nonterminal symbol-number=\"%d\" name=\"%s\"" 
 420                   " usefulness=\"%s\"/>", 
 422                   reduce_nonterminal_useless_in_grammar (i
) 
 423                     ? "useless-in-grammar" : "useful"); 
 425   xml_puts (out
, level 
+ 1, "</nonterminals>"); 
 426   xml_puts (out
, level
, "</grammar>"); 
 430 xml_indent (FILE *out
, int level
) 
 433   for (i 
= 0; i 
< level
; i
++) 
 438 xml_puts (FILE *out
, int level
, char const *s
) 
 440   xml_indent (out
, level
); 
 446 xml_printf (FILE *out
, int level
, char const *fmt
, ...) 
 450   xml_indent (out
, level
); 
 452   va_start (arglist
, fmt
); 
 453   vfprintf (out
, fmt
, arglist
); 
 460 xml_escape_string (struct escape_buf 
*buf
, char const *str
) 
 462   size_t len 
= strlen (str
); 
 463   size_t max_expansion 
= sizeof """ - 1; 
 466   if (buf
->size 
<= max_expansion 
* len
) 
 468       buf
->size 
= max_expansion 
* len 
+ 1; 
 469       buf
->ptr 
= x2realloc (buf
->ptr
, &buf
->size
); 
 476       default: *p
++ = *str
; break; 
 477       case '&': p 
= stpcpy (p
, "&" ); break; 
 478       case '<': p 
= stpcpy (p
, "<"  ); break; 
 479       case '>': p 
= stpcpy (p
, ">"  ); break; 
 480       case '"': p 
= stpcpy (p
, """); break; 
 488 xml_escape_n (int n
, char const *str
) 
 490   return xml_escape_string (escape_bufs 
+ n
, str
); 
 494 xml_escape (char const *str
) 
 496   return xml_escape_n (0, str
); 
 505   FILE *out 
= xfopen (spec_xml_file
, "w"); 
 507   fputs ("<?xml version=\"1.0\"?>\n\n", out
); 
 508   xml_printf (out
, level
, "<bison-xml-report version=\"%s\">", 
 509               xml_escape (VERSION
)); 
 512   xml_printf (out
, level 
+ 1, "<filename>%s</filename>", 
 513               xml_escape (grammar_file
)); 
 516   print_grammar (out
, level 
+ 1); 
 518   new_closure (nritems
); 
 519   no_reduce_set 
=  bitset_create (ntokens
, BITSET_FIXED
); 
 521   /* print automaton */ 
 523   xml_puts (out
, level 
+ 1, "<automaton>"); 
 524   for (i 
= 0; i 
< nstates
; i
++) 
 525     print_state (out
, level 
+ 2, states
[i
]); 
 526   xml_puts (out
, level 
+ 1, "</automaton>"); 
 528   bitset_free (no_reduce_set
); 
 531   xml_puts (out
, 0, "</bison-xml-report>"); 
 533   free (escape_bufs
[0].ptr
); 
 534   free (escape_bufs
[1].ptr
);