1 /* Bison Grammar Parser                             -*- C -*-
 
   2    Copyright (C) 2002 Free Software Foundation, Inc.
 
   4    This file is part of Bison, the GNU Compiler Compiler.
 
   6    This program is free software; you can redistribute it and/or modify
 
   7    it under the terms of the GNU General Public License as published by
 
   8    the Free Software Foundation; either version 2 of the License, or
 
   9    (at your option) any later version.
 
  11    This program is distributed in the hope that it will be useful,
 
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  14    GNU General Public License for more details.
 
  16    You should have received a copy of the GNU General Public License
 
  17    along with this program; if not, write to the Free Software
 
  18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
  34 #include "muscle_tab.h"
 
  41 #include "conflicts.h"
 
  43 /* Produce verbose parse errors.  */
 
  44 #define YYERROR_VERBOSE 1
 
  45 #define YYLLOC_DEFAULT(Current, Rhs, N)                 \
 
  49     Current.first_column  = Rhs[1].first_column;        \
 
  50     Current.first_line    = Rhs[1].first_line;          \
 
  51     Current.last_column   = Rhs[N].last_column;         \
 
  52     Current.last_line     = Rhs[N].last_line;           \
 
  60 /* Pass the control structure to YYPARSE and YYLEX. */
 
  61 #define YYPARSE_PARAM gram_control
 
  62 #define YYLEX_PARAM gram_control
 
  63 /* YYPARSE receives GRAM_CONTROL as a void *.  Provide a
 
  64    correctly typed access to it.  */
 
  65 #define yycontrol ((gram_control_t *) gram_control)
 
  67 /* Request detailed parse error messages, and pass them to GRAM_ERROR.
 
  68    FIXME: depends on the undocumented availability of YYLLOC.t */
 
  70 #define yyerror(Msg) \
 
  71         gram_error (&yylloc, Msg)
 
  73 #define YYPRINT(File, Type, Value) \
 
  74         yyprint (File, Type, &Value)
 
  75 static void yyprint (FILE *file, int type, const yystype *value);
 
  77 symbol_class current_class = unknown_sym;
 
  78 char *current_type = 0;
 
  79 symbol_t *current_lhs;
 
  80 location_t current_lhs_location;
 
  81 assoc_t current_assoc;
 
  83 braced_code_t current_braced_code = action_braced_code;
 
  87 /* Only NUMBERS have a value.  */
 
  97 /* Define the tokens together with their human representation.  */
 
  98 %token GRAM_EOF 0 "end of file"
 
  99 %token STRING     "string"
 
 100 %token CHARACTER  "character"
 
 103 %token PERCENT_TOKEN       "%token"
 
 104 %token PERCENT_NTERM       "%nterm"
 
 106 %token PERCENT_TYPE        "%type"
 
 107 %token PERCENT_DESTRUCTOR  "%destructor"
 
 108 %token PERCENT_PRINTER     "%printer"
 
 110 %token PERCENT_UNION       "%union"
 
 112 %token PERCENT_LEFT        "%left"
 
 113 %token PERCENT_RIGHT       "%right"
 
 114 %token PERCENT_NONASSOC    "%nonassoc"
 
 116 %token PERCENT_PREC          "%prec"
 
 117 %token PERCENT_DPREC         "%dprec"
 
 118 %token PERCENT_MERGE         "%merge"
 
 121 /*----------------------.
 
 122 | Global Declarations.  |
 
 123 `----------------------*/
 
 126   PERCENT_DEBUG         "%debug"
 
 127   PERCENT_DEFINE        "%define"
 
 128   PERCENT_DEFINES       "%defines"
 
 129   PERCENT_ERROR_VERBOSE "%error-verbose"
 
 130   PERCENT_EXPECT        "%expect"
 
 131   PERCENT_FILE_PREFIX   "%file-prefix"
 
 132   PERCENT_GLR_PARSER    "%glr-parser"
 
 133   PERCENT_LEX_PARAM     "%lex-param"
 
 134   PERCENT_LOCATIONS     "%locations"
 
 135   PERCENT_NAME_PREFIX   "%name-prefix"
 
 136   PERCENT_NO_LINES      "%no-lines"
 
 137   PERCENT_OUTPUT        "%output"
 
 138   PERCENT_PARSE_PARAM   "%parse-param"
 
 139   PERCENT_PURE_PARSER   "%pure-parser"
 
 140   PERCENT_SKELETON      "%skeleton"
 
 141   PERCENT_START         "%start"
 
 142   PERCENT_TOKEN_TABLE   "%token-table"
 
 143   PERCENT_VERBOSE       "%verbose"
 
 153 %token ID              "identifier"
 
 154 %token PERCENT_PERCENT "%%"
 
 155 %token PROLOGUE        "%{...%}"
 
 156 %token EPILOGUE        "epilogue"
 
 157 %token BRACED_CODE     "{...}"
 
 160 %type <string> CHARACTER TYPE STRING string_content
 
 161                BRACED_CODE PROLOGUE EPILOGUE epilogue.opt action
 
 163 %type <symbol> ID symbol string_as_id
 
 164 %type <assoc> precedence_declarator
 
 165 %type <list>  symbols.1
 
 169   declarations "%%" grammar epilogue.opt
 
 171       yycontrol->errcode = 0;
 
 172       epilogue_set ($4, @4);
 
 177         /*------------------------------------.
 
 178         | Declarations: before the first %%.  |
 
 179         `------------------------------------*/
 
 183 | declarations declaration semi_colon.opt
 
 188 | PROLOGUE                                 { prologue_augment ($1, @1); }
 
 189 | "%debug"                                 { debug_flag = 1; }
 
 190 | "%define" string_content string_content  { muscle_insert ($2, $3); }
 
 191 | "%defines"                               { defines_flag = 1; }
 
 192 | "%error-verbose"                         { error_verbose = 1; }
 
 193 | "%expect" INT                            { expected_conflicts = $2; }
 
 194 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 
 195 | "%glr-parser"                            { glr_parser = 1; }
 
 196 | "%lex-param" string_content "," string_content
 
 197                            { muscle_pair_list_grow ("lex_param", $2, $4); }
 
 198 | "%locations"                             { locations_flag = 1; }
 
 199 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 
 200 | "%no-lines"                              { no_lines_flag = 1; }
 
 201 | "%output" "=" string_content             { spec_outfile = $3; }
 
 202 | "%parse-param" string_content "," string_content
 
 203                            { muscle_pair_list_grow ("parse_param", $2, $4); }
 
 204 | "%pure-parser"                           { pure_parser = 1; }
 
 205 | "%skeleton" string_content               { skeleton = $2; }
 
 206 | "%token-table"                           { token_table_flag = 1; }
 
 207 | "%verbose"                               { report_flag = 1; }
 
 208 | "%yacc"                                  { yacc_flag = 1; }
 
 212   precedence_declaration
 
 216       grammar_start_symbol_set ($2, @2);
 
 218 | "%union" BRACED_CODE
 
 221       MUSCLE_INSERT_INT ("stype_line", @2.first_line);
 
 222       muscle_insert ("stype", $2);
 
 225     { current_braced_code = destructor_braced_code; }
 
 226   BRACED_CODE symbols.1
 
 229       for (list = $4; list; list = list->next)
 
 230         symbol_destructor_set (list->sym, $3, @3);
 
 231       symbol_list_free ($4);
 
 232       current_braced_code = action_braced_code;
 
 235     { current_braced_code = printer_braced_code; }
 
 236   BRACED_CODE symbols.1
 
 239       for (list = $4; list; list = list->next)
 
 240         symbol_printer_set (list->sym, $3, list->location);
 
 241       symbol_list_free ($4);
 
 242       current_braced_code = action_braced_code;
 
 247   "%nterm" { current_class = nterm_sym; } symbol_defs.1
 
 249       current_class = unknown_sym;
 
 252 | "%token" { current_class = token_sym; } symbol_defs.1
 
 254       current_class = unknown_sym;
 
 257 | "%type" TYPE symbols.1
 
 260       for (list = $3; list; list = list->next)
 
 261         symbol_type_set (list->sym, $2, @2);
 
 262       symbol_list_free ($3);
 
 266 precedence_declaration:
 
 267   precedence_declarator type.opt symbols.1
 
 271       for (list = $3; list; list = list->next)
 
 273           symbol_type_set (list->sym, current_type, @2);
 
 274           symbol_precedence_set (list->sym, current_prec, $1, @1);
 
 276       symbol_list_free ($3);
 
 281 precedence_declarator:
 
 282   "%left"     { $$ = left_assoc; }
 
 283 | "%right"    { $$ = right_assoc; }
 
 284 | "%nonassoc" { $$ = non_assoc; }
 
 288   /* Nothing. */ { current_type = NULL;}
 
 289 | TYPE           { current_type = $1; }
 
 292 /* One or more nonterminals to be %typed. */
 
 295   symbol            { $$ = symbol_list_new ($1, @1); }
 
 296 | symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
 
 299 /* One token definition.  */
 
 307        symbol_class_set ($1, current_class, @1);
 
 308        symbol_type_set ($1, current_type, @1);
 
 312       symbol_class_set ($1, current_class, @1);
 
 313       symbol_type_set ($1, current_type, @1);
 
 314       symbol_user_token_number_set ($1, $2, @2);
 
 318       symbol_class_set ($1, current_class, @1);
 
 319       symbol_type_set ($1, current_type, @1);
 
 320       symbol_make_alias ($1, $2, @$);
 
 322 | ID INT string_as_id
 
 324       symbol_class_set ($1, current_class, @1);
 
 325       symbol_type_set ($1, current_type, @1);
 
 326       symbol_user_token_number_set ($1, $2, @2);
 
 327       symbol_make_alias ($1, $3, @$);
 
 331 /* One or more symbol definitions. */
 
 335 | symbol_defs.1 symbol_def
 
 340         /*------------------------------------------.
 
 341         | The grammar section: between the two %%.  |
 
 342         `------------------------------------------*/
 
 345   rules_or_grammar_declaration
 
 346 | grammar rules_or_grammar_declaration
 
 349 /* As a Bison extension, one can use the grammar declarations in the
 
 350    body of the grammar.  But to remain LALR(1), they must be ended
 
 351    with a semi-colon.  */
 
 352 rules_or_grammar_declaration:
 
 354 | grammar_declaration ";"
 
 357         complain_at (@$, _("POSIX forbids declarations in the grammar"));
 
 366   ID ":" { current_lhs = $1; current_lhs_location = @1; } rhses.1 ";"
 
 371   rhs                { grammar_rule_end (@1); }
 
 372 | rhses.1 "|" rhs    { grammar_rule_end (@3); }
 
 377     { grammar_rule_begin (current_lhs, current_lhs_location); }
 
 379     { grammar_current_rule_symbol_append ($2, @2); }
 
 381     { grammar_current_rule_action_append ($2, @2); }
 
 383     { grammar_current_rule_prec_set ($3, @3); }
 
 385     { grammar_current_rule_dprec_set ($3, @3); }
 
 387     { grammar_current_rule_merge_set ($3, @3); }
 
 392 | string_as_id    { $$ = $1; }
 
 393 | CHARACTER       { $$ = symbol_get ($1, @1); }
 
 401 /* A string used as an ID: we have to keep the quotes. */
 
 405       $$ = symbol_get ($1, @1);
 
 406       symbol_class_set ($$, token_sym, @1);
 
 410 /* A string used for its contents.  Strip the quotes. */
 
 415       $$[strlen ($$) - 1] = '\0';
 
 435 /*------------------------------------------------------------------.
 
 436 | When debugging the parser, display tokens' locations and values.  |
 
 437 `------------------------------------------------------------------*/
 
 441          int type, const yystype *value)
 
 447       fprintf (file, " = '%s'", value->string);
 
 451       fprintf (file, " = %s", value->symbol->tag);
 
 455       fprintf (file, " = %d", value->integer);
 
 459       fprintf (file, " = \"%s\"", value->string);
 
 463       fprintf (file, " = <%s>", value->string);
 
 469       fprintf (file, " = {{ %s }}", value->string);
 
 475 gram_error (location_t *yylloc, const char *msg)
 
 477   complain_at (*yylloc, "%s", msg);