mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-28 13:43:02 +00:00
doc: reformat grammar snippets.
* doc/bison.texinfo: Convert the grammar examples to
use a narrower style. This helps fitting into the
@smallbook constraints.
http://lists.gnu.org/archive/html/bison-patches/2012-03/msg00011.html
(cherry picked from commit 5e9b6624d7)
Conflicts:
doc/bison.texinfo
This commit is contained in:
@@ -637,8 +637,7 @@ the statement; the naked semicolon, and the colon, are Bison punctuation
|
||||
used in every rule.
|
||||
|
||||
@example
|
||||
stmt: RETURN expr ';'
|
||||
;
|
||||
stmt: RETURN expr ';' ;
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -710,8 +709,7 @@ For example, here is a rule that says an expression can be the sum of
|
||||
two subexpressions:
|
||||
|
||||
@example
|
||||
expr: expr '+' expr @{ $$ = $1 + $3; @}
|
||||
;
|
||||
expr: expr '+' expr @{ $$ = $1 + $3; @} ;
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@@ -890,24 +888,26 @@ parses a vastly simplified form of Pascal type declarations.
|
||||
%%
|
||||
|
||||
@group
|
||||
type_decl : TYPE ID '=' type ';'
|
||||
;
|
||||
type_decl: TYPE ID '=' type ';' ;
|
||||
@end group
|
||||
|
||||
@group
|
||||
type : '(' id_list ')'
|
||||
type:
|
||||
'(' id_list ')'
|
||||
| expr DOTDOT expr
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
id_list : ID
|
||||
id_list:
|
||||
ID
|
||||
| id_list ',' ID
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
expr : '(' expr ')'
|
||||
expr:
|
||||
'(' expr ')'
|
||||
| expr '+' expr
|
||||
| expr '-' expr
|
||||
| expr '*' expr
|
||||
@@ -994,27 +994,32 @@ Let's consider an example, vastly simplified from a C++ grammar.
|
||||
%%
|
||||
|
||||
prog:
|
||||
/* Nothing. */
|
||||
| prog stmt @{ printf ("\n"); @}
|
||||
;
|
||||
|
||||
stmt : expr ';' %dprec 1
|
||||
stmt:
|
||||
expr ';' %dprec 1
|
||||
| decl %dprec 2
|
||||
;
|
||||
|
||||
expr : ID @{ printf ("%s ", $$); @}
|
||||
expr:
|
||||
ID @{ printf ("%s ", $$); @}
|
||||
| TYPENAME '(' expr ')'
|
||||
@{ printf ("%s <cast> ", $1); @}
|
||||
| expr '+' expr @{ printf ("+ "); @}
|
||||
| expr '=' expr @{ printf ("= "); @}
|
||||
;
|
||||
|
||||
decl : TYPENAME declarator ';'
|
||||
decl:
|
||||
TYPENAME declarator ';'
|
||||
@{ printf ("%s <declare> ", $1); @}
|
||||
| TYPENAME declarator '=' expr ';'
|
||||
@{ printf ("%s <init-declare> ", $1); @}
|
||||
;
|
||||
|
||||
declarator : ID @{ printf ("\"%s\" ", $1); @}
|
||||
declarator:
|
||||
ID @{ printf ("\"%s\" ", $1); @}
|
||||
| '(' declarator ')'
|
||||
;
|
||||
@end example
|
||||
@@ -1085,7 +1090,8 @@ other. To do so, you could change the declaration of @code{stmt} as
|
||||
follows:
|
||||
|
||||
@example
|
||||
stmt : expr ';' %merge <stmtMerge>
|
||||
stmt:
|
||||
expr ';' %merge <stmtMerge>
|
||||
| decl %merge <stmtMerge>
|
||||
;
|
||||
@end example
|
||||
@@ -1494,19 +1500,22 @@ Here are the grammar rules for the reverse polish notation calculator.
|
||||
|
||||
@example
|
||||
@group
|
||||
input: /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
line: '\n'
|
||||
| exp '\n' @{ printf ("\t%.10g\n", $1); @}
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("%.10g\n", $1); @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
exp: NUM @{ $$ = $1; @}
|
||||
exp:
|
||||
NUM @{ $$ = $1; @}
|
||||
| exp exp '+' @{ $$ = $1 + $2; @}
|
||||
| exp exp '-' @{ $$ = $1 - $2; @}
|
||||
| exp exp '*' @{ $$ = $1 * $2; @}
|
||||
@@ -1548,7 +1557,8 @@ rule are referred to as @code{$1}, @code{$2}, and so on.
|
||||
Consider the definition of @code{input}:
|
||||
|
||||
@example
|
||||
input: /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end example
|
||||
@@ -1582,8 +1592,9 @@ input tokens; we will arrange for the latter to happen at end-of-input.
|
||||
Now consider the definition of @code{line}:
|
||||
|
||||
@example
|
||||
line: '\n'
|
||||
| exp '\n' @{ printf ("\t%.10g\n", $1); @}
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("%.10g\n", $1); @}
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -1610,7 +1621,8 @@ The second handles an addition-expression, which looks like two expressions
|
||||
followed by a plus-sign. The third handles subtraction, and so on.
|
||||
|
||||
@example
|
||||
exp: NUM
|
||||
exp:
|
||||
NUM
|
||||
| exp exp '+' @{ $$ = $1 + $2; @}
|
||||
| exp exp '-' @{ $$ = $1 - $2; @}
|
||||
@dots{}
|
||||
@@ -1652,7 +1664,8 @@ exp : NUM | exp exp '+' @{$$ = $1 + $2; @} | @dots{} ;
|
||||
means the same thing as this:
|
||||
|
||||
@example
|
||||
exp: NUM
|
||||
exp:
|
||||
NUM
|
||||
| exp exp '+' @{ $$ = $1 + $2; @}
|
||||
| @dots{}
|
||||
;
|
||||
@@ -1899,19 +1912,22 @@ parentheses nested to arbitrary depth. Here is the Bison code for
|
||||
|
||||
%% /* The grammar follows. */
|
||||
@group
|
||||
input: /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
line: '\n'
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("\t%.10g\n", $1); @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
exp: NUM @{ $$ = $1; @}
|
||||
exp:
|
||||
NUM @{ $$ = $1; @}
|
||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||
@@ -1981,7 +1997,8 @@ been added to one of the alternatives for @code{line}:
|
||||
|
||||
@example
|
||||
@group
|
||||
line: '\n'
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("\t%.10g\n", $1); @}
|
||||
| error '\n' @{ yyerrok; @}
|
||||
;
|
||||
@@ -2074,19 +2091,22 @@ wrong expressions or subexpressions.
|
||||
|
||||
@example
|
||||
@group
|
||||
input : /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
line : '\n'
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("%d\n", $1); @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
exp : NUM @{ $$ = $1; @}
|
||||
exp:
|
||||
NUM @{ $$ = $1; @}
|
||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||
@@ -2334,7 +2354,8 @@ those which mention @code{VAR} or @code{FNCT}, are new.
|
||||
@comment file: mfcalc.y
|
||||
@example
|
||||
@group
|
||||
input: /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end group
|
||||
@@ -2342,13 +2363,14 @@ input: /* empty */
|
||||
@group
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("\t%.10g\n", $1); @}
|
||||
| exp '\n' @{ printf ("%.10g\n", $1); @}
|
||||
| error '\n' @{ yyerrok; @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
exp: NUM @{ $$ = $1; @}
|
||||
exp:
|
||||
NUM @{ $$ = $1; @}
|
||||
| VAR @{ $$ = $1->value.var; @}
|
||||
| VAR '=' exp @{ $$ = $3; $1->value.var = $3; @}
|
||||
| FNCT '(' exp ')' @{ $$ = (*($1->value.fnctptr))($3); @}
|
||||
@@ -3261,8 +3283,7 @@ A Bison grammar rule has the following general form:
|
||||
|
||||
@example
|
||||
@group
|
||||
@var{result}: @var{components}@dots{}
|
||||
;
|
||||
@var{result}: @var{components}@dots{};
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3275,8 +3296,7 @@ For example,
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: exp '+' exp
|
||||
;
|
||||
exp: exp '+' exp;
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3321,7 +3341,8 @@ be joined with the vertical-bar character @samp{|} as follows:
|
||||
|
||||
@example
|
||||
@group
|
||||
@var{result}: @var{rule1-components}@dots{}
|
||||
@var{result}:
|
||||
@var{rule1-components}@dots{}
|
||||
| @var{rule2-components}@dots{}
|
||||
@dots{}
|
||||
;
|
||||
@@ -3337,13 +3358,15 @@ comma-separated sequence of zero or more @code{exp} groupings:
|
||||
|
||||
@example
|
||||
@group
|
||||
expseq: /* empty */
|
||||
expseq:
|
||||
/* empty */
|
||||
| expseq1
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
expseq1: exp
|
||||
expseq1:
|
||||
exp
|
||||
| expseq1 ',' exp
|
||||
;
|
||||
@end group
|
||||
@@ -3365,7 +3388,8 @@ comma-separated sequence of one or more expressions:
|
||||
|
||||
@example
|
||||
@group
|
||||
expseq1: exp
|
||||
expseq1:
|
||||
exp
|
||||
| expseq1 ',' exp
|
||||
;
|
||||
@end group
|
||||
@@ -3380,7 +3404,8 @@ the same construct is defined using @dfn{right recursion}:
|
||||
|
||||
@example
|
||||
@group
|
||||
expseq1: exp
|
||||
expseq1:
|
||||
exp
|
||||
| exp ',' expseq1
|
||||
;
|
||||
@end group
|
||||
@@ -3406,13 +3431,15 @@ For example:
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: primary
|
||||
expr:
|
||||
primary
|
||||
| primary '+' primary
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
primary: constant
|
||||
primary:
|
||||
constant
|
||||
| '(' expr ')'
|
||||
;
|
||||
@end group
|
||||
@@ -3536,9 +3563,9 @@ Here is a typical example:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
| exp '+' exp
|
||||
@{ $$ = $1 + $3; @}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3546,9 +3573,9 @@ Or, in terms of named references:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp[result]: @dots{}
|
||||
| exp[left] '+' exp[right]
|
||||
@{ $result = $left + $right; @}
|
||||
exp[result]:
|
||||
@dots{}
|
||||
| exp[left] '+' exp[right] @{ $result = $left + $right; @}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3595,14 +3622,15 @@ is a case in which you can use this reliably:
|
||||
|
||||
@example
|
||||
@group
|
||||
foo: expr bar '+' expr @{ @dots{} @}
|
||||
foo:
|
||||
expr bar '+' expr @{ @dots{} @}
|
||||
| expr bar '-' expr @{ @dots{} @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
bar: /* empty */
|
||||
@{ previous_expr = $0; @}
|
||||
bar:
|
||||
/* empty */ @{ previous_expr = $0; @}
|
||||
;
|
||||
@end group
|
||||
@end example
|
||||
@@ -3633,9 +3661,9 @@ in the rule. In this example,
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
| exp '+' exp
|
||||
@{ $$ = $1 + $3; @}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3702,11 +3730,11 @@ remove it afterward. Here is how it is done:
|
||||
|
||||
@example
|
||||
@group
|
||||
stmt: LET '(' var ')'
|
||||
@{ $<context>$ = push_context ();
|
||||
declare_variable ($3); @}
|
||||
stmt @{ $$ = $6;
|
||||
pop_context ($<context>5); @}
|
||||
stmt:
|
||||
LET '(' var ')'
|
||||
@{ $<context>$ = push_context (); declare_variable ($3); @}
|
||||
stmt
|
||||
@{ $$ = $6; pop_context ($<context>5); @}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3748,15 +3776,19 @@ declare a destructor for that symbol:
|
||||
|
||||
%%
|
||||
|
||||
stmt: let stmt
|
||||
@{ $$ = $2;
|
||||
pop_context ($1); @}
|
||||
;
|
||||
stmt:
|
||||
let stmt
|
||||
@{
|
||||
$$ = $2;
|
||||
pop_context ($1);
|
||||
@};
|
||||
|
||||
let: LET '(' var ')'
|
||||
@{ $$ = push_context ();
|
||||
declare_variable ($3); @}
|
||||
;
|
||||
let:
|
||||
LET '(' var ')'
|
||||
@{
|
||||
$$ = push_context ();
|
||||
declare_variable ($3);
|
||||
@};
|
||||
|
||||
@end group
|
||||
@end example
|
||||
@@ -3775,7 +3807,8 @@ declaration or not:
|
||||
|
||||
@example
|
||||
@group
|
||||
compound: '@{' declarations statements '@}'
|
||||
compound:
|
||||
'@{' declarations statements '@}'
|
||||
| '@{' statements '@}'
|
||||
;
|
||||
@end group
|
||||
@@ -3786,7 +3819,8 @@ But when we add a mid-rule action as follows, the rules become nonfunctional:
|
||||
|
||||
@example
|
||||
@group
|
||||
compound: @{ prepare_for_local_variables (); @}
|
||||
compound:
|
||||
@{ prepare_for_local_variables (); @}
|
||||
'@{' declarations statements '@}'
|
||||
@end group
|
||||
@group
|
||||
@@ -3808,7 +3842,8 @@ actions into the two rules, like this:
|
||||
|
||||
@example
|
||||
@group
|
||||
compound: @{ prepare_for_local_variables (); @}
|
||||
compound:
|
||||
@{ prepare_for_local_variables (); @}
|
||||
'@{' declarations statements '@}'
|
||||
| @{ prepare_for_local_variables (); @}
|
||||
'@{' statements '@}'
|
||||
@@ -3826,7 +3861,8 @@ does work is to put the action after the open-brace, like this:
|
||||
|
||||
@example
|
||||
@group
|
||||
compound: '@{' @{ prepare_for_local_variables (); @}
|
||||
compound:
|
||||
'@{' @{ prepare_for_local_variables (); @}
|
||||
declarations statements '@}'
|
||||
| '@{' statements '@}'
|
||||
;
|
||||
@@ -3842,17 +3878,15 @@ serves as a subroutine:
|
||||
|
||||
@example
|
||||
@group
|
||||
subroutine: /* empty */
|
||||
@{ prepare_for_local_variables (); @}
|
||||
subroutine:
|
||||
/* empty */ @{ prepare_for_local_variables (); @}
|
||||
;
|
||||
|
||||
@end group
|
||||
|
||||
@group
|
||||
compound: subroutine
|
||||
'@{' declarations statements '@}'
|
||||
| subroutine
|
||||
'@{' statements '@}'
|
||||
compound:
|
||||
subroutine '@{' declarations statements '@}'
|
||||
| subroutine '@{' statements '@}'
|
||||
;
|
||||
@end group
|
||||
@end example
|
||||
@@ -3938,7 +3972,8 @@ Here is a basic example using the default data type for locations:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '/' exp
|
||||
@{
|
||||
@@$.first_column = @@1.first_column;
|
||||
@@ -3969,7 +4004,8 @@ example above simply rewrites this way:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '/' exp
|
||||
@{
|
||||
if ($3)
|
||||
@@ -6355,13 +6391,15 @@ factorial operators (@samp{!}), and allow parentheses for grouping.
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: term '+' expr
|
||||
expr:
|
||||
term '+' expr
|
||||
| term
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
term: '(' expr ')'
|
||||
term:
|
||||
'(' expr ')'
|
||||
| term '!'
|
||||
| NUMBER
|
||||
;
|
||||
@@ -6471,7 +6509,8 @@ the conflict:
|
||||
%%
|
||||
@end group
|
||||
@group
|
||||
stmt: expr
|
||||
stmt:
|
||||
expr
|
||||
| if_stmt
|
||||
;
|
||||
@end group
|
||||
@@ -6483,7 +6522,8 @@ if_stmt:
|
||||
;
|
||||
@end group
|
||||
|
||||
expr: variable
|
||||
expr:
|
||||
variable
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -6512,7 +6552,8 @@ input @w{@samp{1 - 2 * 3}} can be parsed in two different ways):
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: expr '-' expr
|
||||
expr:
|
||||
expr '-' expr
|
||||
| expr '*' expr
|
||||
| expr '<' expr
|
||||
| '(' expr ')'
|
||||
@@ -6671,7 +6712,8 @@ Now the precedence of @code{UMINUS} can be used in specific rules:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '-' exp
|
||||
@dots{}
|
||||
| '-' exp %prec UMINUS
|
||||
@@ -6740,19 +6782,17 @@ of zero or more @code{word} groupings.
|
||||
|
||||
@example
|
||||
@group
|
||||
sequence: /* empty */
|
||||
@{ printf ("empty sequence\n"); @}
|
||||
sequence:
|
||||
/* empty */ @{ printf ("empty sequence\n"); @}
|
||||
| maybeword
|
||||
| sequence word
|
||||
@{ printf ("added word %s\n", $2); @}
|
||||
| sequence word @{ printf ("added word %s\n", $2); @}
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
maybeword: /* empty */
|
||||
@{ printf ("empty maybeword\n"); @}
|
||||
| word
|
||||
@{ printf ("single word %s\n", $1); @}
|
||||
maybeword:
|
||||
/* empty */ @{ printf ("empty maybeword\n"); @}
|
||||
| word @{ printf ("single word %s\n", $1); @}
|
||||
;
|
||||
@end group
|
||||
@end example
|
||||
@@ -6781,26 +6821,28 @@ reduce/reduce conflict must be studied and usually eliminated. Here is the
|
||||
proper way to define @code{sequence}:
|
||||
|
||||
@example
|
||||
sequence: /* empty */
|
||||
@{ printf ("empty sequence\n"); @}
|
||||
| sequence word
|
||||
@{ printf ("added word %s\n", $2); @}
|
||||
sequence:
|
||||
/* empty */ @{ printf ("empty sequence\n"); @}
|
||||
| sequence word @{ printf ("added word %s\n", $2); @}
|
||||
;
|
||||
@end example
|
||||
|
||||
Here is another common error that yields a reduce/reduce conflict:
|
||||
|
||||
@example
|
||||
sequence: /* empty */
|
||||
sequence:
|
||||
/* empty */
|
||||
| sequence words
|
||||
| sequence redirects
|
||||
;
|
||||
|
||||
words: /* empty */
|
||||
words:
|
||||
/* empty */
|
||||
| words word
|
||||
;
|
||||
|
||||
redirects:/* empty */
|
||||
redirects:
|
||||
/* empty */
|
||||
| redirects redirect
|
||||
;
|
||||
@end example
|
||||
@@ -6821,7 +6863,8 @@ Here are two ways to correct these rules. First, to make it a single level
|
||||
of sequence:
|
||||
|
||||
@example
|
||||
sequence: /* empty */
|
||||
sequence:
|
||||
/* empty */
|
||||
| sequence word
|
||||
| sequence redirect
|
||||
;
|
||||
@@ -6832,20 +6875,23 @@ from being empty:
|
||||
|
||||
@example
|
||||
@group
|
||||
sequence: /* empty */
|
||||
sequence:
|
||||
/* empty */
|
||||
| sequence words
|
||||
| sequence redirects
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
words: word
|
||||
words:
|
||||
word
|
||||
| words word
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
redirects:redirect
|
||||
redirects:
|
||||
redirect
|
||||
| redirects redirect
|
||||
;
|
||||
@end group
|
||||
@@ -6863,8 +6909,7 @@ Here is an example:
|
||||
%token ID
|
||||
|
||||
%%
|
||||
def: param_spec return_spec ','
|
||||
;
|
||||
def: param_spec return_spec ',';
|
||||
param_spec:
|
||||
type
|
||||
| name_list ':' type
|
||||
@@ -6877,12 +6922,10 @@ return_spec:
|
||||
;
|
||||
@end group
|
||||
@group
|
||||
type: ID
|
||||
;
|
||||
type: ID;
|
||||
@end group
|
||||
@group
|
||||
name: ID
|
||||
;
|
||||
name: ID;
|
||||
name_list:
|
||||
name
|
||||
| name ',' name_list
|
||||
@@ -6937,8 +6980,7 @@ distinct. In the above example, adding one rule to
|
||||
return_spec:
|
||||
type
|
||||
| name ':' type
|
||||
/* This rule is never used. */
|
||||
| ID BOGUS
|
||||
| ID BOGUS /* This rule is never used. */
|
||||
;
|
||||
@end group
|
||||
@end example
|
||||
@@ -7540,7 +7582,8 @@ in the current context, the parse can continue.
|
||||
For example:
|
||||
|
||||
@example
|
||||
stmnts: /* empty string */
|
||||
stmnts:
|
||||
/* empty string */
|
||||
| stmnts '\n'
|
||||
| stmnts exp '\n'
|
||||
| stmnts error '\n'
|
||||
@@ -7584,7 +7627,8 @@ close-delimiter will probably appear to be unmatched, and generate another,
|
||||
spurious error message:
|
||||
|
||||
@example
|
||||
primary: '(' expr ')'
|
||||
primary:
|
||||
'(' expr ')'
|
||||
| '(' error ')'
|
||||
@dots{}
|
||||
;
|
||||
@@ -7709,16 +7753,14 @@ duplication, with actions omitted for brevity:
|
||||
@example
|
||||
@group
|
||||
initdcl:
|
||||
declarator maybeasm '='
|
||||
init
|
||||
declarator maybeasm '=' init
|
||||
| declarator maybeasm
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
notype_initdcl:
|
||||
notype_declarator maybeasm '='
|
||||
init
|
||||
notype_declarator maybeasm '=' init
|
||||
| notype_declarator maybeasm
|
||||
;
|
||||
@end group
|
||||
@@ -7761,15 +7803,12 @@ as an identifier if it appears in that context. Here is how you can do it:
|
||||
@dots{}
|
||||
@end group
|
||||
@group
|
||||
expr: IDENTIFIER
|
||||
expr:
|
||||
IDENTIFIER
|
||||
| constant
|
||||
| HEX '('
|
||||
@{ hexflag = 1; @}
|
||||
expr ')'
|
||||
@{ hexflag = 0;
|
||||
$$ = $4; @}
|
||||
| expr '+' expr
|
||||
@{ $$ = make_sum ($1, $3); @}
|
||||
| HEX '(' @{ hexflag = 1; @}
|
||||
expr ')' @{ hexflag = 0; $$ = $4; @}
|
||||
| expr '+' expr @{ $$ = make_sum ($1, $3); @}
|
||||
@dots{}
|
||||
;
|
||||
@end group
|
||||
@@ -7804,11 +7843,11 @@ For example, in C-like languages, a typical error recovery rule is to skip
|
||||
tokens until the next semicolon, and then start a new statement, like this:
|
||||
|
||||
@example
|
||||
stmt: expr ';'
|
||||
stmt:
|
||||
expr ';'
|
||||
| IF '(' expr ')' stmt @{ @dots{} @}
|
||||
@dots{}
|
||||
error ';'
|
||||
@{ hexflag = 0; @}
|
||||
| error ';' @{ hexflag = 0; @}
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -7826,9 +7865,9 @@ and skips to the close-parenthesis:
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: @dots{}
|
||||
| '(' expr ')'
|
||||
@{ $$ = $2; @}
|
||||
expr:
|
||||
@dots{}
|
||||
| '(' expr ')' @{ $$ = $2; @}
|
||||
| '(' error ')'
|
||||
@dots{}
|
||||
@end group
|
||||
@@ -7888,7 +7927,8 @@ The following grammar file, @file{calc.y}, will be used in the sequel:
|
||||
%left '+' '-'
|
||||
%left '*'
|
||||
%%
|
||||
exp: exp '+' exp
|
||||
exp:
|
||||
exp '+' exp
|
||||
| exp '-' exp
|
||||
| exp '*' exp
|
||||
| exp '/' exp
|
||||
@@ -9302,8 +9342,9 @@ The grammar itself is straightforward.
|
||||
%start unit;
|
||||
unit: assignments exp @{ driver.result = $2; @};
|
||||
|
||||
assignments: assignments assignment @{@}
|
||||
| /* Nothing. */ @{@};
|
||||
assignments:
|
||||
/* Nothing. */ @{@}
|
||||
| assignments assignment @{@};
|
||||
|
||||
assignment:
|
||||
"identifier" ":=" exp
|
||||
@@ -10313,7 +10354,8 @@ real start-symbol:
|
||||
@example
|
||||
%token START_FOO START_BAR;
|
||||
%start start;
|
||||
start: START_FOO foo
|
||||
start:
|
||||
START_FOO foo
|
||||
| START_BAR bar;
|
||||
@end example
|
||||
|
||||
|
||||
Reference in New Issue
Block a user