X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/24ec08374334f3c4cfb4080384793aa423e29679..d4fca427636f15eb952974ff04e4fb046428440a:/doc/bison.texinfo diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 0f5dbbb3..ea7f6c8a 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -1791,7 +1791,7 @@ yylex (void) /* Skip white space. */ while ((c = getchar ()) == ' ' || c == '\t') - ; + continue; @end group @group /* Process numbers. */ @@ -2240,6 +2240,7 @@ yylex (void) if (c == EOF) return 0; +@group /* Return a single char, and update location. */ if (c == '\n') @{ @@ -2250,6 +2251,7 @@ yylex (void) ++yylloc.last_column; return c; @} +@end group @end example Basically, the lexical analyzer performs the same processing as before: @@ -2306,11 +2308,15 @@ to create named variables, store values in them, and use them later. Here is a sample session with the multi-function calculator: @example +@group $ @kbd{mfcalc} @kbd{pi = 3.141592653589} @result{} 3.1415926536 +@end group +@group @kbd{sin(pi)} @result{} 0.0000000000 +@end group @kbd{alpha = beta1 = 2.3} @result{} 2.3000000000 @kbd{alpha} @@ -2540,6 +2546,7 @@ found, a pointer to that symbol is returned; otherwise zero is returned. #include /* malloc. */ #include /* strlen. */ +@group symrec * putsym (char const *sym_name, int sym_type) @{ @@ -2553,7 +2560,9 @@ putsym (char const *sym_name, int sym_type) sym_table = ptr; return ptr; @} +@end group +@group symrec * getsym (char const *sym_name) @{ @@ -2564,6 +2573,7 @@ getsym (char const *sym_name) return ptr; return 0; @} +@end group @end smallexample @node Mfcalc Lexer @@ -2597,7 +2607,8 @@ yylex (void) int c; /* Ignore white space, get first nonwhite character. */ - while ((c = getchar ()) == ' ' || c == '\t'); + while ((c = getchar ()) == ' ' || c == '\t') + continue; if (c == EOF) return 0; @@ -2949,19 +2960,26 @@ definitions. Thus, they belong in one or more @code{%code requires}: @smallexample +@group %code top @{ #define _GNU_SOURCE #include @} +@end group +@group %code requires @{ #include "ptypes.h" @} +@end group +@group %union @{ long int n; tree t; /* @r{@code{tree} is defined in @file{ptypes.h}.} */ @} +@end group +@group %code requires @{ #define YYLTYPE YYLTYPE typedef struct YYLTYPE @@ -2973,12 +2991,15 @@ Thus, they belong in one or more @code{%code requires}: char *filename; @} YYLTYPE; @} +@end group +@group %code @{ static void print_token_value (FILE *, int, YYSTYPE); #define YYPRINT(F, N, L) print_token_value (F, N, L) static void trace_token (enum yytokentype token, YYLTYPE loc); @} +@end group @dots{} @end smallexample @@ -3016,19 +3037,26 @@ sufficient. Instead, move its prototype from the unqualified @code{%code} to a @code{%code provides}: @smallexample +@group %code top @{ #define _GNU_SOURCE #include @} +@end group +@group %code requires @{ #include "ptypes.h" @} +@end group +@group %union @{ long int n; tree t; /* @r{@code{tree} is defined in @file{ptypes.h}.} */ @} +@end group +@group %code requires @{ #define YYLTYPE YYLTYPE typedef struct YYLTYPE @@ -3040,15 +3068,20 @@ sufficient. Instead, move its prototype from the unqualified char *filename; @} YYLTYPE; @} +@end group +@group %code provides @{ void trace_token (enum yytokentype token, YYLTYPE loc); @} +@end group +@group %code @{ static void print_token_value (FILE *, int, YYSTYPE); #define YYPRINT(F, N, L) print_token_value (F, N, L) @} +@end group @dots{} @end smallexample @@ -3078,15 +3111,19 @@ For example, you may organize semantic-type-related directives by semantic type: @smallexample +@group %code requires @{ #include "type1.h" @} %union @{ type1 field1; @} %destructor @{ type1_free ($$); @} %printer @{ type1_print ($$); @} +@end group +@group %code requires @{ #include "type2.h" @} %union @{ type2 field2; @} %destructor @{ type2_free ($$); @} %printer @{ type2_print ($$); @} +@end group @end smallexample @noindent @@ -7023,18 +7060,22 @@ For example, here is an erroneous attempt to define a sequence of zero or more @code{word} groupings. @example +@group sequence: /* empty */ @{ printf ("empty sequence\n"); @} | maybeword | sequence word @{ printf ("added word %s\n", $2); @} ; +@end group +@group maybeword: /* empty */ @{ printf ("empty maybeword\n"); @} | word @{ printf ("single word %s\n", $1); @} ; +@end group @end example @noindent @@ -7111,18 +7152,24 @@ Second, to prevent either a @code{words} or a @code{redirects} from being empty: @example +@group sequence: /* empty */ | sequence words | sequence redirects ; +@end group +@group words: word | words word ; +@end group +@group redirects:redirect | redirects redirect ; +@end group @end example @node Mysterious Conflicts @@ -7964,11 +8011,13 @@ earlier: @example typedef int foo, bar; int baz (void) +@group @{ static bar (bar); /* @r{redeclare @code{bar} as static variable} */ extern foo foo (foo); /* @r{redeclare @code{foo} as function} */ return foo (bar); @} +@end group @end example Unfortunately, the name being declared is separated from the declaration @@ -7981,17 +8030,21 @@ declaration in which that can't be done. Here is a part of the duplication, with actions omitted for brevity: @example +@group initdcl: declarator maybeasm '=' init | declarator maybeasm ; +@end group +@group notype_initdcl: notype_declarator maybeasm '=' init | notype_declarator maybeasm ; +@end group @end example @noindent @@ -8246,6 +8299,7 @@ Grammar and reports the uses of the symbols: @example +@group Terminals, with rules where they appear $end (0) 0 @@ -8255,13 +8309,16 @@ $end (0) 0 '/' (47) 4 error (256) NUM (258) 5 +@end group +@group Nonterminals, with rules where they appear $accept (8) on left: 0 exp (9) on left: 1 2 3 4 5, on right: 0 1 2 3 4 +@end group @end example @noindent @@ -8478,6 +8535,7 @@ state 8 The remaining states are similar: @example +@group state 9 exp -> exp . '+' exp (rule 1) @@ -8491,7 +8549,9 @@ state 9 '/' [reduce using rule 2 (exp)] $default reduce using rule 2 (exp) +@end group +@group state 10 exp -> exp . '+' exp (rule 1) @@ -8504,7 +8564,9 @@ state 10 '/' [reduce using rule 3 (exp)] $default reduce using rule 3 (exp) +@end group +@group state 11 exp -> exp . '+' exp (rule 1) @@ -8523,6 +8585,7 @@ state 11 '*' [reduce using rule 4 (exp)] '/' [reduce using rule 4 (exp)] $default reduce using rule 4 (exp) +@end group @end example @noindent @@ -9921,15 +9984,19 @@ preceding tokens. Comments would be treated equally. @comment file: calc++-scanner.ll @example +@group %@{ // Code run each time a pattern is matched. # define YY_USER_ACTION loc.columns (yyleng); %@} +@end group %% +@group %@{ // Code run each time yylex is called. loc.step (); %@} +@end group @{blank@}+ loc.step (); [\n]+ loc.lines (yyleng); loc.step (); @end example @@ -9947,6 +10014,7 @@ The rules are simple. The driver is used to report errors. ")" return yy::calcxx_parser::make_RPAREN(loc); ":=" return yy::calcxx_parser::make_ASSIGN(loc); +@group @{int@} @{ errno = 0; long n = strtol (yytext, NULL, 10); @@ -9954,6 +10022,7 @@ The rules are simple. The driver is used to report errors. driver.error (loc, "integer is out of range"); return yy::calcxx_parser::make_NUMBER(n, loc); @} +@end group @{id@} return yy::calcxx_parser::make_IDENTIFIER(yytext, loc); . driver.error (loc, "invalid character"); <> return yy::calcxx_parser::make_END(loc); @@ -9966,6 +10035,7 @@ on the scanner's data, it is simpler to implement them in this file. @comment file: calc++-scanner.ll @example +@group void calcxx_driver::scan_begin () @{ @@ -9978,12 +10048,15 @@ calcxx_driver::scan_begin () exit (EXIT_FAILURE); @} @} +@end group +@group void calcxx_driver::scan_end () @{ fclose (yyin); @} +@end group @end example @node Calc++ Top Level @@ -9996,6 +10069,7 @@ The top level file, @file{calc++.cc}, poses no problem. #include #include "calc++-driver.hh" +@group int main (int argc, char *argv[]) @{ @@ -10012,6 +10086,7 @@ main (int argc, char *argv[]) res = 1; return res; @} +@end group @end example @node Java Parsers @@ -10696,41 +10771,49 @@ speed, they might not notice a change of input file. As a demonstration, consider the following source file, @file{first-line.l}: -@verbatim -%{ +@example +@group +%@{ #include #include -%} +%@} +@end group %% .*\n ECHO; return 1; %% +@group int yyparse (char const *file) -{ +@{ yyin = fopen (file, "r"); if (!yyin) - { - perror ("fopen"); - exit (EXIT_FAILURE); - } + @{ + perror ("fopen"); + exit (EXIT_FAILURE); + @} +@end group +@group /* One token only. */ yylex (); if (fclose (yyin) != 0) - { - perror ("fclose"); - exit (EXIT_FAILURE); - } + @{ + perror ("fclose"); + exit (EXIT_FAILURE); + @} return 0; -} +@} +@end group +@group int main (void) -{ +@{ yyparse ("input"); yyparse ("input"); return 0; -} -@end verbatim +@} +@end group +@end example @noindent If the file @file{input} contains @@ -10780,14 +10863,19 @@ Bison lists, but is only concerned with a misunderstanding of the role of the scanner. Consider the following Lex code: @verbatim +@group %{ #include char *yylval = NULL; %} +@end group +@group %% .* yylval = yytext; return 1; \n /* IGNORE */ %% +@end group +@group int main () { @@ -10797,6 +10885,7 @@ main () printf ("\"%s\", \"%s\"\n", fst, snd); return 0; } +@end group @end verbatim If you compile and run this code, you get: