mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-16 15:53:03 +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:
@@ -106,11 +106,12 @@ static void unexpected_newline (boundary, char const *);
|
||||
/* A complex tag, with nested angles brackets. */
|
||||
%x SC_TAG
|
||||
|
||||
/* Three types of user code:
|
||||
/* Four types of user code:
|
||||
- prologue (code between `%{' `%}' in the first section, before %%);
|
||||
- actions, printers, union, etc, (between braced in the middle section);
|
||||
- epilogue (everything after the second %%). */
|
||||
%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE
|
||||
- epilogue (everything after the second %%).
|
||||
- predicate (code between `%?{' and `{' in middle section); */
|
||||
%x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE SC_PREDICATE
|
||||
/* C and C++ comments in code. */
|
||||
%x SC_COMMENT SC_LINE_COMMENT
|
||||
/* Strings and characters in code. */
|
||||
@@ -285,6 +286,13 @@ splice (\\[ \f\t\v]*\n)*
|
||||
BEGIN SC_BRACED_CODE;
|
||||
}
|
||||
|
||||
/* Semantic predicate. */
|
||||
"%?"[ \f\n\t\v]*"{" {
|
||||
nesting = 0;
|
||||
code_start = loc->start;
|
||||
BEGIN SC_PREDICATE;
|
||||
}
|
||||
|
||||
/* A type. */
|
||||
"<*>" return TAG_ANY;
|
||||
"<>" return TAG_NONE;
|
||||
@@ -661,7 +669,7 @@ splice (\\[ \f\t\v]*\n)*
|
||||
| Strings, comments etc. can be found in user code. |
|
||||
`---------------------------------------------------*/
|
||||
|
||||
<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
|
||||
<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE,SC_PREDICATE>
|
||||
{
|
||||
"'" {
|
||||
STRING_GROW;
|
||||
@@ -691,14 +699,32 @@ splice (\\[ \f\t\v]*\n)*
|
||||
|
||||
|
||||
/*-----------------------------------------------------------.
|
||||
| Scanning some code in braces (actions). The initial "{" is |
|
||||
| already eaten. |
|
||||
| Scanning some code in braces (actions, predicates). The |
|
||||
| initial "{" is already eaten. |
|
||||
`-----------------------------------------------------------*/
|
||||
|
||||
<SC_BRACED_CODE>
|
||||
<SC_BRACED_CODE,SC_PREDICATE>
|
||||
{
|
||||
"{"|"<"{splice}"%" STRING_GROW; nesting++;
|
||||
"%"{splice}">" STRING_GROW; nesting--;
|
||||
|
||||
/* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
|
||||
(as `<' `<%'). */
|
||||
"<"{splice}"<" STRING_GROW;
|
||||
|
||||
<<EOF>> {
|
||||
int token = (YY_START == SC_BRACED_CODE) ? BRACED_CODE : BRACED_PREDICATE;
|
||||
unexpected_eof (code_start, "}");
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
<SC_BRACED_CODE>
|
||||
{
|
||||
"}" {
|
||||
obstack_1grow (&obstack_for_string, '}');
|
||||
|
||||
@@ -712,21 +738,24 @@ splice (\\[ \f\t\v]*\n)*
|
||||
return BRACED_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
|
||||
(as `<' `<%'). */
|
||||
"<"{splice}"<" STRING_GROW;
|
||||
|
||||
<<EOF>> {
|
||||
unexpected_eof (code_start, "}");
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return BRACED_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
<SC_PREDICATE>
|
||||
{
|
||||
"}" {
|
||||
--nesting;
|
||||
if (nesting < 0)
|
||||
{
|
||||
STRING_FINISH;
|
||||
loc->start = code_start;
|
||||
val->code = last_string;
|
||||
BEGIN INITIAL;
|
||||
return BRACED_PREDICATE;
|
||||
}
|
||||
else
|
||||
obstack_1grow (&obstack_for_string, '}');
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------.
|
||||
| Scanning some prologue: from "%{" (already scanned) to "%}". |
|
||||
@@ -774,8 +803,8 @@ splice (\\[ \f\t\v]*\n)*
|
||||
| By default, grow the string obstack with the input. |
|
||||
`-----------------------------------------------------*/
|
||||
|
||||
<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>. |
|
||||
<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>\n STRING_GROW;
|
||||
<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>. |
|
||||
<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE>\n STRING_GROW;
|
||||
|
||||
%%
|
||||
|
||||
|
||||
Reference in New Issue
Block a user