From: Paul Eggert Date: Tue, 30 Sep 2003 20:11:29 +0000 (+0000) Subject: Add %default-prec. X-Git-Tag: BISON-2_0~206 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/39a06c251ad9c523b1172835e545d2043431873d Add %default-prec. --- diff --git a/ChangeLog b/ChangeLog index 466d8de8..616fe3fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2003-09-30 Frank Heckenbach + and Paul Eggert + + * 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 + + * tests/testsuite.at: Include local.at, not input.at, fixing + a typo in the 2003-08-25 patch. + 2003-08-27 Akim Demaille * data/lalr1.cc (yyparse) [__GNUC__]: "Use" yyerrorlab to pacify diff --git a/doc/bison.texinfo b/doc/bison.texinfo index b316d430..d69fc169 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -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}. diff --git a/src/parse-gram.y b/src/parse-gram.y index 42c5e96e..642a97cc 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -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: diff --git a/src/reader.c b/src/reader.c index 0adee6fc..1cd035cc 100644 --- a/src/reader.c +++ b/src/reader.c @@ -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; diff --git a/src/reader.h b/src/reader.h index a86f139f..fc6ee7d6 100644 --- a/src/reader.h +++ b/src/reader.h @@ -73,5 +73,6 @@ void free_merger_functions (void); extern merger_list *merge_functions; extern bool typed; +extern bool default_prec; #endif /* !READER_H_ */ diff --git a/src/scan-gram.l b/src/scan-gram.l index 56e65cfe..a3275015 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -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; diff --git a/tests/conflicts.at b/tests/conflicts.at index 3b51d6f0..259827bd 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -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