mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
multistart: use b4_accept instead of action post-processing
For each start symbol, generate a parsing function with a richer
return value than the usual of yyparse. Reserve a place for the
returned semantic value, in order to avoid having to pass a pointer as
argument to "return" that value. This also makes the call to the
parsing function independent of whether a given start-symbol is typed.
For instance, if the grammar file contains:
%type <int> expression
%start input expression
(so "input" is valueless) we get
typedef struct
{
int yystatus;
} yyparse_input_t;
yyparse_input_t yyparse_input (void);
typedef struct
{
int yyvalue;
int yystatus;
} yyparse_expression_t;
yyparse_expression_t yyparse_expression (void);
This commit also changes the implementation of the parser termination:
when there are multiple start symbols, it is the initial rules that
explicitly YYACCEPT. They do that after having exported the
start-symbol's value (if it is typed):
switch (yyn)
{
case 1: /* $accept: YY_EXPRESSION expression $end */
{ ((*yyvalue).TOK_expression) = (yyvsp[-1].TOK_expression); YYACCEPT; }
break;
case 2: /* $accept: YY_INPUT input $end */
{ YYACCEPT; }
break;
I have tried several ways to deal with termination, and this is the
one that appears the best one to me. It is also the most natural.
* src/scan-code.h, src/scan-code.l (obstack_for_actions): New.
* src/reader.c (grammar_rule_check_and_complete): Generate the actions
of the rules for each start symbol.
* data/skeletons/bison.m4 (b4_symbol_slot): New, with safer semantics
than type and type_tag.
* data/skeletons/yacc.c (b4_accept): New.
Generates the body of the action of the start rules.
(_b4_declare_sub_yyparse): For each start symbol define a dedicated
return type for its parsing function.
Adjust the declaration of its parsing function.
(_b4_define_sub_yyparse): Adjust the definition of the function.
* examples/c/lexcalc/parse.y: Check the case of valueless symbols.
* examples/c/lexcalc/lexcalc.test: Check start symbols.
This commit is contained in:
@@ -46,15 +46,15 @@ EOF
|
||||
run 1 'err: 1.1-11: error: division by zero'
|
||||
|
||||
|
||||
# Multistart: parse "line" instead of "input".
|
||||
# Multistart: parse "expression" instead of "input".
|
||||
cat >input <<EOF
|
||||
1+2*3
|
||||
EOF
|
||||
run 0 7 -l
|
||||
run 0 'expression: 7' -e
|
||||
|
||||
cat >input <<EOF
|
||||
1
|
||||
2
|
||||
EOF
|
||||
run 1 '1
|
||||
err: 2.1: syntax error, unexpected number, expecting end of file' -l
|
||||
run 1 'expression: failure
|
||||
err: 2.1: syntax error, unexpected number, expecting end of file' -e
|
||||
|
||||
@@ -76,10 +76,10 @@
|
||||
;
|
||||
|
||||
%token <int> NUM "number"
|
||||
%type <int> exp
|
||||
%type <int> exp expression line
|
||||
%printer { fprintf (yyo, "%d", $$); } <int>
|
||||
|
||||
%start input line
|
||||
%start input expression
|
||||
|
||||
// Precedence (from lowest to highest) and associativity.
|
||||
%left "+" "-"
|
||||
@@ -93,8 +93,12 @@ input:
|
||||
;
|
||||
|
||||
line:
|
||||
exp EOL { printf ("%d\n", $exp); }
|
||||
| error EOL { yyerrok; }
|
||||
exp EOL { $$ = $exp; printf ("%d\n", $$); }
|
||||
| error EOL { $$ = 0; yyerrok; }
|
||||
;
|
||||
|
||||
expression:
|
||||
exp EOL { $$ = $exp; }
|
||||
;
|
||||
|
||||
exp:
|
||||
@@ -129,16 +133,22 @@ int main (int argc, const char *argv[])
|
||||
int nerrs = 0;
|
||||
// Possibly enable parser runtime debugging.
|
||||
yydebug = !!getenv ("YYDEBUG");
|
||||
int parse_expression_p = 0;
|
||||
// Enable parse traces on option -p.
|
||||
int parse_line_p = 0;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
if (1 < argc && strcmp (argv[1], "-p") == 0)
|
||||
yydebug = 1;
|
||||
else if (strcmp (argv[i], "-l") == 0)
|
||||
parse_line_p = 1;
|
||||
else if (strcmp (argv[i], "-e") == 0)
|
||||
parse_expression_p = 1;
|
||||
|
||||
if (parse_line_p)
|
||||
yyparse_line (&nerrs);
|
||||
if (parse_expression_p)
|
||||
{
|
||||
yyparse_expression_t res = yyparse_expression (&nerrs);
|
||||
if (res.yystatus == 0)
|
||||
printf ("expression: %d\n", res.yyvalue);
|
||||
else
|
||||
printf ("expression: failure\n");
|
||||
}
|
||||
else
|
||||
yyparse_input (&nerrs);
|
||||
// Exit on failure if there were errors.
|
||||
|
||||
Reference in New Issue
Block a user