mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
Allow specification of semantic predicates.
These changes allow users to prefix an action with %? to indicate that it
is a semantic predicate---an expression that is evaluated immediately (not
deferred, even in GLR nondeterministic mode) and causes a syntax error if
false. In GLR parsers, this has the effect of killing one of a set of
split-off parses, just as would an ordinary syntax error.
Changelog:
* NEWS: Describe new semantic-predicate feature.
* data/c.m4 (b4_predicate_case): New definition.
* data/java.m4 (b4_predicate_case): New definition.
* data/glr.c (yyimmediate): Add definition.
(yydoAction): Remove comment, now obsolete.
Do YY_REDUCE_PRINT here.
(yyglrReduce): Alter comment to indicate that semantic values
need not be deferred.
Remove YY_REDUCE_PRINT from here; done in yydoAction.
(yyprocessOneStack): Pass immediate flag.
Delete stacks rejected by predicates in newly split-off parsers.
Change handling of yyerr so that only current stack gets deleted
when semantic predicate fails.
(yyfillin): Don't crash if a semantic value is unresolved (as may
happen in predicate rules).
Copy lr state as well in debugging mode.
Update comment on setting of yysval to include yyloc as well.
(yy_reduce_print): Add yynormal argument. Perform fillin properly.
Report unresolved RHS values.
(yyimmediate): New table.
* src/gram.h (struct rule): Add is_predicate field.
* src/output.c (user_actions_output): Use b4_predicate_case for
predicates.
(prepare_symbols): Output yyimmediate.
* src/scan-gram.l: Add %? token, SC_PREDICATE state.
* src/scan-code.l (code_props_rule_action_init): Add is_predicate
argument.
* src/scan-code.h (struct code_props): Add is_predicate field.
(code_props_rule_action_init): New interface.
* src/parse-gram.y (%?{...}): New token.
(rhs): Add %?{...} rule.
* src/parse-gram.c: Regenerate.
* src/parse-gram.h: Regenerate.
* src/reader.c (grammar_current_rule_action_append): Add
immediate argument.
(grammar_midrule_action): Use new interface for
code_props_rule_action_init.
(grammar_current_rule_action_append): Ditto.
(packgram): Transfer is_predicate value.
* src/reader.h (grammar_current_rule_action_append): New interface.
* doc/bison.texinfo: Document semantic predicates (%?).
* data/glr.c (yylhsNonterm, yyisDefaultedState,yyDefaultAction)
(yygetLRActions,yynewGLRStackItem,yyaddDeferredAction,yyinitStateSet)
(yyinitGLRStack,yyexpandGLRStack,yyupdateSplit,yymarkStackDeleted)
(yyundeleteLastStack,yyglrShift,yyglrShiftDefer,yydoAction,yyglrReduce)
(yyidenticalOptions,yymergeOptionSets,yyresolveStates,yyresolveAction)
(yyresolveLocations,yyresolveValue,yyreducePrint): Update parameter
names in comments and mention all parameters.
(struct yyGLRState): Fix description of yyposn field.
(yyresolveLocations): Correct comment so as not to imply action when
yyn1==0.
This commit is contained in:
@@ -136,6 +136,7 @@ Writing @acronym{GLR} Parsers
|
||||
* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars.
|
||||
* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Deferred semantic actions have special concerns.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler.
|
||||
|
||||
Examples
|
||||
@@ -758,6 +759,7 @@ merged result.
|
||||
* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars.
|
||||
* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities.
|
||||
* GLR Semantic Actions:: Deferred semantic actions have special concerns.
|
||||
* Semantic Predicates:: Controlling a parse with arbitrary computations.
|
||||
* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler.
|
||||
@end menu
|
||||
|
||||
@@ -1163,6 +1165,65 @@ In a deferred semantic action, its effect is undefined.
|
||||
Also, see @ref{Location Default Action, ,Default Action for Locations}, which
|
||||
describes a special usage of @code{YYLLOC_DEFAULT} in @acronym{GLR} parsers.
|
||||
|
||||
@node Semantic Predicates
|
||||
@subsection Controlling a Parse with Arbitrary Predicates
|
||||
@findex %?
|
||||
@cindex Semantic predicates in @acronym{GLR} parsers
|
||||
|
||||
In addition to the @code{%dprec} and @code{%merge} directives,
|
||||
@acronym{GLR} parsers
|
||||
allow you to reject parses on the basis of arbitrary computations executed
|
||||
in user code, without having Bison treat this rejection as an error
|
||||
if there are alternative parses. (This feature is experimental and may
|
||||
evolve. We welcome user feedback.) For example,
|
||||
|
||||
@smallexample
|
||||
widget :
|
||||
%?@{ new_syntax @} "widget" id new_args @{ $$ = f($3, $4); @}
|
||||
| %?@{ !new_syntax @} "widget" id old_args @{ $$ = f($3, $4); @}
|
||||
;
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
is one way to allow the same parser to handle two different syntaxes for
|
||||
widgets. The clause preceded by @code{%?} is treated like an ordinary
|
||||
action, except that its text is treated as an expression and is always
|
||||
evaluated immediately (even when in nondeterministic mode). If the
|
||||
expression yields 0 (false), the clause is treated as a syntax error,
|
||||
which, in a nondeterministic parser, causes the stack in which it is reduced
|
||||
to die. In a deterministic parser, it acts like YYERROR.
|
||||
|
||||
As the example shows, predicates otherwise look like semantic actions, and
|
||||
therefore you must be take them into account when determining the numbers
|
||||
to use for denoting the semantic values of right-hand side symbols.
|
||||
Predicate actions, however, have no defined value, and may not be given
|
||||
labels.
|
||||
|
||||
There is a subtle difference between semantic predicates and ordinary
|
||||
actions in nondeterministic mode, since the latter are deferred.
|
||||
For example, we could try to rewrite the previous example as
|
||||
|
||||
@smallexample
|
||||
widget :
|
||||
@{ if (!new_syntax) YYERROR; @} "widget" id new_args @{ $$ = f($3, $4); @}
|
||||
| @{ if (new_syntax) YYERROR; @} "widget" id old_args @{ $$ = f($3, $4); @}
|
||||
;
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
(reversing the sense of the predicate tests to cause an error when they are
|
||||
false). However, this
|
||||
does @emph{not} have the same effect if @code{new_args} and @code{old_args}
|
||||
have overlapping syntax.
|
||||
Since the mid-rule actions testing @code{new_syntax} are deferred,
|
||||
a @acronym{GLR} parser first encounters the unresolved ambiguous reduction
|
||||
for cases where @code{new_args} and @code{old_args} recognize the same string
|
||||
@emph{before} performing the tests of @code{new_syntax}. It therefore
|
||||
reports an error.
|
||||
|
||||
Finally, be careful in writing predicates: deferred actions have not been
|
||||
evaluated, so that using them in a predicate will have undefined effects.
|
||||
|
||||
@node Compiler Requirements
|
||||
@subsection Considerations when Compiling @acronym{GLR} Parsers
|
||||
@cindex @code{inline}
|
||||
@@ -10610,6 +10671,19 @@ file. @xref{Grammar Outline, ,Outline of a Bison
|
||||
Grammar}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Directive} %?@{@var{expression}@}
|
||||
Predicate actions. This is a type of action clause that may appear in
|
||||
rules. The expression is evaluated, and if false, causes a syntax error. In
|
||||
@acronym{GLR} parsers during nondeterministic operation,
|
||||
this silently causes an alternative parse to die. During deterministic
|
||||
operation, it is the same as the effect of YYERROR.
|
||||
@xref{Semantic Predicates}.
|
||||
|
||||
This feature is experimental.
|
||||
More user feedback will help to determine whether it should become a permanent
|
||||
feature.
|
||||
@end deffn
|
||||
|
||||
@deffn {Construct} /*@dots{}*/
|
||||
Comment delimiters, as in C.
|
||||
@end deffn
|
||||
|
||||
Reference in New Issue
Block a user