* doc/bison.texi: Change the comments into explicit %empty.
+ With help from Joel E. Denny and Gabriel Rassoul.
+
Empty rules (i.e., with an empty right-hand side) can now be explicitly
marked by the new %empty directive. Using %empty on a non-empty rule is
an error. The new -Wempty-rule warning reports empty rules without
Empty rules (i.e., with an empty right-hand side) can now be explicitly
marked by the new %empty directive. Using %empty on a non-empty rule is
an error. The new -Wempty-rule warning reports empty rules without
- /* nothing */ { /* Generates an empty string list */ }
+ %empty { /* Generates an empty string list. */ }
| list item ";" { std::swap ($$, $1); $$.push_back ($2); }
;
| list item ";" { std::swap ($$, $1); $$.push_back ($2); }
;
| prog stmt @{ printf ("\n"); @}
;
| prog stmt @{ printf ("\n"); @}
;
| input line
;
@end group
| input line
;
@end group
| input line
;
@end example
| input line
;
@end example
colon and the first @samp{|}; this means that @code{input} can match an
empty string of input (no tokens). We write the rules this way because it
is legitimate to type @kbd{Ctrl-d} right after you start the calculator.
colon and the first @samp{|}; this means that @code{input} can match an
empty string of input (no tokens). We write the rules this way because it
is legitimate to type @kbd{Ctrl-d} right after you start the calculator.
-It's conventional to put an empty alternative first and write the comment
-@samp{/* empty */} in it.
+It's conventional to put an empty alternative first and to use the
+(optional) @code{%empty} directive, or to write the comment @samp{/* empty
+*/} in it (@pxref{Empty Rules}).
The second alternate rule (@code{input line}) handles all nontrivial input.
It means, ``After reading any number of lines, read one more line if
The second alternate rule (@code{input line}) handles all nontrivial input.
It means, ``After reading any number of lines, read one more line if
%% /* The grammar follows. */
@group
input:
%% /* The grammar follows. */
@group
input:
| input line
;
@end group
| input line
;
@end group
| input line
;
@end group
| input line
;
@end group
%% /* The grammar follows. */
@group
input:
%% /* The grammar follows. */
@group
input:
| input line
;
@end group
| input line
;
@end group
- /* empty */ @{ previous_expr = $0; @}
+ %empty @{ previous_expr = $0; @}
;
@end group
@end example
;
@end group
@end example
is translated into:
@example
is translated into:
@example
-$@@1: /* empty */ @{ a(); @};
-$@@2: /* empty */ @{ c(); @};
-$@@3: /* empty */ @{ d(); @};
+$@@1: %empty @{ a(); @};
+$@@2: %empty @{ c(); @};
+$@@3: %empty @{ d(); @};
exp: $@@1 "b" $@@2 $@@3 "e" @{ f(); @};
@end example
exp: $@@1 "b" $@@2 $@@3 "e" @{ f(); @};
@end example
is translated into
@example
is translated into
@example
-@@1: /* empty */ @{ a(); @};
-@@2: /* empty */ @{ $$ = c(); @};
-$@@3: /* empty */ @{ d(); @};
+@@1: %empty @{ a(); @};
+@@2: %empty @{ $$ = c(); @};
+$@@3: %empty @{ d(); @};
exp: @@1 "b" @@2 $@@3 "e" @{ f = $1; @}
@end example
exp: @@1 "b" @@2 $@@3 "e" @{ f = $1; @}
@end example
@example
@group
subroutine:
@example
@group
subroutine:
- /* empty */ @{ prepare_for_local_variables (); @}
+ %empty @{ prepare_for_local_variables (); @}
@example
@group
sequence:
@example
@group
sequence:
- /* empty */ @{ printf ("empty sequence\n"); @}
+ %empty @{ printf ("empty sequence\n"); @}
| maybeword
| sequence word @{ printf ("added word %s\n", $2); @}
;
| maybeword
| sequence word @{ printf ("added word %s\n", $2); @}
;
- /* empty */ @{ printf ("empty maybeword\n"); @}
-| word @{ printf ("single word %s\n", $1); @}
+ %empty @{ printf ("empty maybeword\n"); @}
+| word @{ printf ("single word %s\n", $1); @}
;
@end group
@end example
;
@end group
@end example
@example
@group
sequence:
@example
@group
sequence:
- /* empty */ @{ printf ("empty sequence\n"); @}
+ %empty @{ printf ("empty sequence\n"); @}
| sequence word @{ printf ("added word %s\n", $2); @}
;
@end group
| sequence word @{ printf ("added word %s\n", $2); @}
;
@end group
@example
@group
sequence:
@example
@group
sequence:
| sequence words
| sequence redirects
;
| sequence words
| sequence redirects
;
| words word
;
@end group
@group
redirects:
| words word
;
@end group
@group
redirects:
| redirects redirect
;
@end group
| redirects redirect
;
@end group
| sequence word
| sequence redirect
;
| sequence word
| sequence redirect
;
@example
@group
sequence:
@example
@group
sequence:
| sequence words
| sequence redirects
;
| sequence words
| sequence redirects
;
| sequence word %prec "sequence"
| sequence redirect %prec "sequence"
;
| sequence word %prec "sequence"
| sequence redirect %prec "sequence"
;
| sequence word %prec "word"
| sequence redirect %prec "redirect"
;
| sequence word %prec "word"
| sequence redirect %prec "redirect"
;
| stmts '\n'
| stmts exp '\n'
| stmts error '\n'
| stmts '\n'
| stmts exp '\n'
| stmts error '\n'
unit: assignments exp @{ driver.result = $2; @};
assignments:
unit: assignments exp @{ driver.result = $2; @};
assignments:
| assignments assignment @{@};
assignment:
| assignments assignment @{@};
assignment: