Add %default-prec.

This commit is contained in:
Paul Eggert
2003-09-30 20:11:29 +00:00
parent 7f41b88821
commit 39a06c251a
7 changed files with 141 additions and 3 deletions

View File

@@ -1,3 +1,22 @@
2003-09-30 Frank Heckenbach <frank@g-n-u.de>
and Paul Eggert <eggert@twinsun.com>
* doc/bison.texinfo (Decl Summary, Contextual Precedence,
Table of Symbols): Document %default-prec.
* src/parse-gram.y (PERCENT_DEFAULT_PREC): New token.
(grammar_declaration): Set default_prec on %default-prec.
* src/scan-gram.l (%default-prec): New token.
* src/reader.h (default_prec): New flag.
* src/reader.c: Likewise.
(packgram): Handle it.
* tests/conflicts.at (%default-prec without %prec,
%default-prec with %prec, %default-prec 1): New tests.
2003-09-30 Paul Eggert <eggert@twinsun.com>
* tests/testsuite.at: Include local.at, not input.at, fixing
a typo in the 2003-08-25 patch.
2003-08-27 Akim Demaille <akim@epita.fr>
* data/lalr1.cc (yyparse) [__GNUC__]: "Use" yyerrorlab to pacify

View File

@@ -3679,9 +3679,15 @@ Declare a terminal symbol (token type name) that is left-associative
@deffn {Directive} %nonassoc
Declare a terminal symbol (token type name) that is nonassociative
(using it in a way that would be associative is a syntax error)
@end deffn
(@pxref{Precedence Decl, ,Operator Precedence}).
Using it in a way that would be associative is a syntax error.
@end deffn
@deffn {Directive} %default-prec
Specify whether to assign a precedence to rules lacking an
explicit @code{%prec} modifier
(@pxref{Contextual Precedence, ,Context-Dependent Precedence}).
@end deffn
@deffn {Directive} %type
Declare the type of semantic values for a nonterminal symbol
@@ -4851,6 +4857,26 @@ exp: @dots{}
@end group
@end example
If you forget to append @code{%prec UMINUS} to the rule for unary
minus, Bison silently assumes that minus has its usual precedence.
This kind of problem can be tricky to debug, since one typically
discovers the mistake only by testing the code.
The @code{%default-prec 0;} declaration makes it easier to discover
this kind of problem systematically. It causes rules that lack a
@code{%prec} modifier to have no precedence, even if the last terminal
symbol mentioned in their components has a declared precedence.
If @code{%default-prec 0;} is in effect, you must specify @code{%prec}
for all rules that participate in precedence conflict resolution.
Then you will see any shift/reduce conflict until you tell Bison how
to resolve it, either by changing your grammar or by adding an
explicit precedence. This will probably add declarations to the
grammar, but it helps to protect against incorrect rule precedences.
The effect of @code{%default-prec 0;} can be reversed by giving
@code{%default-prec 1;}, which is the default.
@node Parser States
@section Parser States
@cindex finite-state machine
@@ -6782,6 +6808,12 @@ parsing. @xref{Parser Function, ,The Parser Function @code{yyparse}}.
Equip the parser for debugging. @xref{Decl Summary}.
@end deffn
@deffn {Directive} %default-prec @var{state};
Bison declaration to specify whether to assign a precedence to rules
that lack an explicit @samp{%prec} modifier. @xref{Contextual
Precedence, ,Context-Dependent Precedence}.
@end deffn
@deffn {Directive} %defines
Bison declaration to create a header file meant for the scanner.
@xref{Decl Summary}.

View File

@@ -115,6 +115,7 @@ int current_prec = 0;
%token
PERCENT_DEBUG "%debug"
PERCENT_DEFAULT_PREC "%default-prec"
PERCENT_DEFINE "%define"
PERCENT_DEFINES "%defines"
PERCENT_ERROR_VERBOSE "%error-verbose"
@@ -240,6 +241,13 @@ grammar_declaration:
symbol_printer_set (list->sym, $1, list->location);
symbol_list_free ($2);
}
| "%default-prec" INT
{
if (0 <= $2 && $2 <= 1)
default_prec = $2;
else
complain_at (@1, _("invalid value for `%default-prec'"));
}
;
symbol_declaration:

View File

@@ -41,6 +41,9 @@ merger_list *merge_functions;
/* Has %union been seen? */
bool typed = false;
/* Should rules have a default precedence? */
bool default_prec = true;
/*-----------------------.
| Set the start symbol. |
@@ -409,7 +412,7 @@ packgram (void)
ritem[itemno++] = symbol_number_as_item_number (p->sym->number);
/* A rule gets by default the precedence and associativity
of the last token in it. */
if (p->sym->class == token_sym)
if (p->sym->class == token_sym && default_prec)
rules[ruleno].prec = p->sym;
if (p)
p = p->next;

View File

@@ -73,5 +73,6 @@ void free_merger_functions (void);
extern merger_list *merge_functions;
extern bool typed;
extern bool default_prec;
#endif /* !READER_H_ */

View File

@@ -182,6 +182,7 @@ splice (\\[ \f\t\v]*\n)*
{
"%binary" return PERCENT_NONASSOC;
"%debug" return PERCENT_DEBUG;
"%default"[-_]"prec" return PERCENT_DEFAULT_PREC;
"%define" return PERCENT_DEFINE;
"%defines" return PERCENT_DEFINES;
"%destructor" token_type = PERCENT_DESTRUCTOR; BEGIN SC_PRE_CODE;

View File

@@ -548,3 +548,77 @@ AT_CHECK([bison -o input.c input.y], 0, [],
input.y: warning: expected 0 reduce/reduce conflicts
])
AT_CLEANUP
## ---------------------------- ##
## %default-prec without %prec ##
## ---------------------------- ##
AT_SETUP([%default-prec without %prec])
AT_DATA([[input.y]],
[[%left '+'
%left '*'
%%
%default-prec 0;
e: e '+' e
| e '*' e
| '0'
;
]])
AT_CHECK([bison -o input.c input.y], 0, [],
[[input.y: conflicts: 4 shift/reduce
]])
AT_CLEANUP
## ------------------------- ##
## %default-prec with %prec ##
## ------------------------- ##
AT_SETUP([%default-prec with %prec])
AT_DATA([[input.y]],
[[%left '+'
%left '*'
%%
%default-prec 0;
e: e '+' e %prec '+'
| e '*' e %prec '*'
| '0'
;
]])
AT_CHECK([bison -o input.c input.y])
AT_CLEANUP
## ---------------- ##
## %default-prec 1 ##
## ---------------- ##
AT_SETUP([%default-prec 1])
AT_DATA([[input.y]],
[[%left '+'
%left '*'
%%
%default-prec 1;
e: e '+' e
| e '*' e
| '0'
;
]])
AT_CHECK([bison -o input.c input.y])
AT_CLEANUP