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