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
This commit is contained in:
@@ -641,8 +641,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
|
||||
@@ -714,8 +713,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
|
||||
@@ -895,24 +893,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
|
||||
@@ -999,27 +999,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
|
||||
@@ -1090,7 +1095,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
|
||||
@@ -1574,19 +1580,22 @@ Here are the grammar rules for the reverse polish notation calculator.
|
||||
@comment file: rpcalc.y
|
||||
@example
|
||||
@group
|
||||
input: /* empty */
|
||||
input:
|
||||
/* empty */
|
||||
| input line
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
line: '\n'
|
||||
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; @}
|
||||
@@ -1628,7 +1637,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
|
||||
@@ -1662,7 +1672,8 @@ input tokens; we will arrange for the latter to happen at end-of-input.
|
||||
Now consider the definition of @code{line}:
|
||||
|
||||
@example
|
||||
line: '\n'
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' @{ printf ("%.10g\n", $1); @}
|
||||
;
|
||||
@end example
|
||||
@@ -1690,7 +1701,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{}
|
||||
@@ -1732,7 +1744,8 @@ exp : NUM | exp exp '+' @{$$ = $1 + $2; @} | @dots{} ;
|
||||
means the same thing as this:
|
||||
|
||||
@example
|
||||
exp: NUM
|
||||
exp:
|
||||
NUM
|
||||
| exp exp '+' @{ $$ = $1 + $2; @}
|
||||
| @dots{}
|
||||
;
|
||||
@@ -1982,19 +1995,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; @}
|
||||
@@ -2065,7 +2081,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; @}
|
||||
;
|
||||
@@ -2158,19 +2175,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; @}
|
||||
@@ -2425,7 +2445,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
|
||||
@@ -2439,7 +2460,8 @@ line:
|
||||
@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); @}
|
||||
@@ -3362,8 +3384,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
|
||||
|
||||
@@ -3376,8 +3397,7 @@ For example,
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: exp '+' exp
|
||||
;
|
||||
exp: exp '+' exp;
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3422,7 +3442,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{}
|
||||
;
|
||||
@@ -3438,13 +3459,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
|
||||
@@ -3466,7 +3489,8 @@ comma-separated sequence of one or more expressions:
|
||||
|
||||
@example
|
||||
@group
|
||||
expseq1: exp
|
||||
expseq1:
|
||||
exp
|
||||
| expseq1 ',' exp
|
||||
;
|
||||
@end group
|
||||
@@ -3481,7 +3505,8 @@ the same construct is defined using @dfn{right recursion}:
|
||||
|
||||
@example
|
||||
@group
|
||||
expseq1: exp
|
||||
expseq1:
|
||||
exp
|
||||
| exp ',' expseq1
|
||||
;
|
||||
@end group
|
||||
@@ -3507,13 +3532,15 @@ For example:
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: primary
|
||||
expr:
|
||||
primary
|
||||
| primary '+' primary
|
||||
;
|
||||
@end group
|
||||
|
||||
@group
|
||||
primary: constant
|
||||
primary:
|
||||
constant
|
||||
| '(' expr ')'
|
||||
;
|
||||
@end group
|
||||
@@ -3637,9 +3664,9 @@ Here is a typical example:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
| exp '+' exp
|
||||
@{ $$ = $1 + $3; @}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@@ -3647,9 +3674,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
|
||||
|
||||
@@ -3696,14 +3723,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
|
||||
@@ -3734,9 +3762,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
|
||||
|
||||
@@ -3803,11 +3831,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
|
||||
|
||||
@@ -3849,15 +3877,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
|
||||
@@ -3876,7 +3908,8 @@ declaration or not:
|
||||
|
||||
@example
|
||||
@group
|
||||
compound: '@{' declarations statements '@}'
|
||||
compound:
|
||||
'@{' declarations statements '@}'
|
||||
| '@{' statements '@}'
|
||||
;
|
||||
@end group
|
||||
@@ -3887,7 +3920,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
|
||||
@@ -3909,7 +3943,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 '@}'
|
||||
@@ -3927,7 +3962,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 '@}'
|
||||
;
|
||||
@@ -3943,17 +3979,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
|
||||
@@ -4039,7 +4073,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;
|
||||
@@ -4070,7 +4105,8 @@ example above simply rewrites this way:
|
||||
|
||||
@example
|
||||
@group
|
||||
exp: @dots{}
|
||||
exp:
|
||||
@dots{}
|
||||
| exp '/' exp
|
||||
@{
|
||||
if ($3)
|
||||
@@ -6635,13 +6671,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
|
||||
;
|
||||
@@ -6751,7 +6789,8 @@ the conflict:
|
||||
%%
|
||||
@end group
|
||||
@group
|
||||
stmt: expr
|
||||
stmt:
|
||||
expr
|
||||
| if_stmt
|
||||
;
|
||||
@end group
|
||||
@@ -6763,7 +6802,8 @@ if_stmt:
|
||||
;
|
||||
@end group
|
||||
|
||||
expr: variable
|
||||
expr:
|
||||
variable
|
||||
;
|
||||
@end example
|
||||
|
||||
@@ -6793,7 +6833,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 ')'
|
||||
@@ -7003,7 +7044,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
|
||||
@@ -7072,19 +7114,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
|
||||
@@ -7113,26 +7153,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
|
||||
@@ -7153,7 +7195,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
|
||||
;
|
||||
@@ -7164,20 +7207,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
|
||||
@@ -7195,8 +7241,7 @@ Here is an example:
|
||||
%token ID
|
||||
|
||||
%%
|
||||
def: param_spec return_spec ','
|
||||
;
|
||||
def: param_spec return_spec ',';
|
||||
param_spec:
|
||||
type
|
||||
| name_list ':' type
|
||||
@@ -7209,12 +7254,10 @@ return_spec:
|
||||
;
|
||||
@end group
|
||||
@group
|
||||
type: ID
|
||||
;
|
||||
type: ID;
|
||||
@end group
|
||||
@group
|
||||
name: ID
|
||||
;
|
||||
name: ID;
|
||||
name_list:
|
||||
name
|
||||
| name ',' name_list
|
||||
@@ -7269,8 +7312,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
|
||||
@@ -7874,7 +7916,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'
|
||||
@@ -7918,7 +7961,8 @@ close-delimiter will probably appear to be unmatched, and generate another,
|
||||
spurious error message:
|
||||
|
||||
@example
|
||||
primary: '(' expr ')'
|
||||
primary:
|
||||
'(' expr ')'
|
||||
| '(' error ')'
|
||||
@dots{}
|
||||
;
|
||||
@@ -8043,16 +8087,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
|
||||
@@ -8095,15 +8137,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
|
||||
@@ -8138,11 +8177,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
|
||||
|
||||
@@ -8160,9 +8199,9 @@ and skips to the close-parenthesis:
|
||||
|
||||
@example
|
||||
@group
|
||||
expr: @dots{}
|
||||
| '(' expr ')'
|
||||
@{ $$ = $2; @}
|
||||
expr:
|
||||
@dots{}
|
||||
| '(' expr ')' @{ $$ = $2; @}
|
||||
| '(' error ')'
|
||||
@dots{}
|
||||
@end group
|
||||
@@ -8222,7 +8261,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
|
||||
@@ -9902,8 +9942,8 @@ Location Tracking Calculator: @code{ltcalc}}).
|
||||
unit: assignments exp @{ driver.result = $2; @};
|
||||
|
||||
assignments:
|
||||
assignments assignment @{@}
|
||||
| /* Nothing. */ @{@};
|
||||
/* Nothing. */ @{@}
|
||||
| assignments assignment @{@};
|
||||
|
||||
assignment:
|
||||
"identifier" ":=" exp @{ driver.variables[$1] = $3; @};
|
||||
@@ -10973,7 +11013,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