mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 01:03:04 +00:00
doc: modernize the examples
* doc/bison.texi: Prefer 'fun' to 'fnct'. Reduce local variable scopes. Prefer strdup to malloc + strcpy. Avoid gratuitous casts. Use simpler names (e.g., 'name' instead of 'fname'). Avoid uses of 0 for NULL. Avoid using NULL when possible (e.g., 'p' instead of 'p != NULL'). Prefer union names to casts (e.g. 'yylval.VAR = s' instead of '*((symrec**) &yylval) = s'). Give arguments a name in fun declarations. Use our typedefs instead of duplicating them (func_t). Stop promoting an explicit $$ = $1;, it should be implicit (Bison might be able to eliminate useless chain rules). Help a bit Texinfo by making smaller groups. Rely on the C compiler to call function pointers (prefer '$1->value.fun ($3)' to (*($1->value.fnctptr))($3)').
This commit is contained in:
181
doc/bison.texi
181
doc/bison.texi
@@ -1543,7 +1543,8 @@ The source code for this calculator is named @file{rpcalc.y}. The
|
|||||||
@subsection Declarations for @code{rpcalc}
|
@subsection Declarations for @code{rpcalc}
|
||||||
|
|
||||||
Here are the C and Bison declarations for the Reverse Polish Notation
|
Here are the C and Bison declarations for the Reverse Polish Notation
|
||||||
calculator. As in C, comments are placed between @samp{/*@dots{}*/}.
|
calculator. As in C, comments are placed between @samp{/*@dots{}*/} or
|
||||||
|
after @samp{//}.
|
||||||
|
|
||||||
@comment file: rpcalc.y
|
@comment file: rpcalc.y
|
||||||
@example
|
@example
|
||||||
@@ -1618,7 +1619,7 @@ line:
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
exp:
|
exp:
|
||||||
NUM @{ $$ = $1; @}
|
NUM
|
||||||
| exp exp '+' @{ $$ = $1 + $2; @}
|
| exp exp '+' @{ $$ = $1 + $2; @}
|
||||||
| exp exp '-' @{ $$ = $1 - $2; @}
|
| exp exp '-' @{ $$ = $1 - $2; @}
|
||||||
| exp exp '*' @{ $$ = $1 * $2; @}
|
| exp exp '*' @{ $$ = $1 * $2; @}
|
||||||
@@ -1720,9 +1721,10 @@ value of the user's input line, that value is no longer needed.
|
|||||||
@subsubsection Explanation of @code{expr}
|
@subsubsection Explanation of @code{expr}
|
||||||
|
|
||||||
The @code{exp} grouping has several rules, one for each kind of expression.
|
The @code{exp} grouping has several rules, one for each kind of expression.
|
||||||
The first rule handles the simplest expressions: those that are just numbers.
|
The first rule handles the simplest expressions: those that are just
|
||||||
The second handles an addition-expression, which looks like two expressions
|
numbers. The second handles an addition-expression, which looks like two
|
||||||
followed by a plus-sign. The third handles subtraction, and so on.
|
expressions followed by a plus-sign. The third handles subtraction, and so
|
||||||
|
on.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
exp:
|
exp:
|
||||||
@@ -1737,9 +1739,9 @@ We have used @samp{|} to join all the rules for @code{exp}, but we could
|
|||||||
equally well have written them separately:
|
equally well have written them separately:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
exp: NUM ;
|
exp: NUM;
|
||||||
exp: exp exp '+' @{ $$ = $1 + $2; @};
|
exp: exp exp '+' @{ $$ = $1 + $2; @};
|
||||||
exp: exp exp '-' @{ $$ = $1 - $2; @};
|
exp: exp exp '-' @{ $$ = $1 - $2; @};
|
||||||
@dots{}
|
@dots{}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -1748,17 +1750,21 @@ terms of the value of its parts. For example, in the rule for addition,
|
|||||||
@code{$1} refers to the first component @code{exp} and @code{$2} refers to
|
@code{$1} refers to the first component @code{exp} and @code{$2} refers to
|
||||||
the second one. The third component, @code{'+'}, has no meaningful
|
the second one. The third component, @code{'+'}, has no meaningful
|
||||||
associated semantic value, but if it had one you could refer to it as
|
associated semantic value, but if it had one you could refer to it as
|
||||||
@code{$3}. When @code{yyparse} recognizes a sum expression using this
|
@code{$3}. The first rule relies on the implicit default action: @samp{@{
|
||||||
rule, the sum of the two subexpressions' values is produced as the value of
|
$$ = $1; @}}.
|
||||||
the entire expression. @xref{Actions}.
|
|
||||||
|
|
||||||
You don't have to give an action for every rule. When a rule has no
|
|
||||||
action, Bison by default copies the value of @code{$1} into @code{$$}.
|
|
||||||
This is what happens in the first rule (the one that uses @code{NUM}).
|
|
||||||
|
|
||||||
The formatting shown here is the recommended convention, but Bison does
|
When @code{yyparse} recognizes a sum expression using this rule, the sum of
|
||||||
not require it. You can add or change white space as much as you wish.
|
the two subexpressions' values is produced as the value of the entire
|
||||||
For example, this:
|
expression. @xref{Actions}.
|
||||||
|
|
||||||
|
You don't have to give an action for every rule. When a rule has no action,
|
||||||
|
Bison by default copies the value of @code{$1} into @code{$$}. This is what
|
||||||
|
happens in the first rule (the one that uses @code{NUM}).
|
||||||
|
|
||||||
|
The formatting shown here is the recommended convention, but Bison does not
|
||||||
|
require it. You can add or change white space as much as you wish. For
|
||||||
|
example, this:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
exp: NUM | exp exp '+' @{$$ = $1 + $2; @} | @dots{} ;
|
exp: NUM | exp exp '+' @{$$ = $1 + $2; @} | @dots{} ;
|
||||||
@@ -1831,11 +1837,10 @@ Here is the code for the lexical analyzer:
|
|||||||
int
|
int
|
||||||
yylex (void)
|
yylex (void)
|
||||||
@{
|
@{
|
||||||
int c;
|
int c = getchar ();
|
||||||
|
|
||||||
/* Skip white space. */
|
/* Skip white space. */
|
||||||
while ((c = getchar ()) == ' ' || c == '\t')
|
while (c == ' ' || c == '\t')
|
||||||
continue;
|
c = getchar ();
|
||||||
@end group
|
@end group
|
||||||
@group
|
@group
|
||||||
/* Process numbers. */
|
/* Process numbers. */
|
||||||
@@ -1848,10 +1853,11 @@ yylex (void)
|
|||||||
@end group
|
@end group
|
||||||
@group
|
@group
|
||||||
/* Return end-of-input. */
|
/* Return end-of-input. */
|
||||||
if (c == EOF)
|
else if (c == EOF)
|
||||||
return 0;
|
return 0;
|
||||||
/* Return a single char. */
|
/* Return a single char. */
|
||||||
return c;
|
else
|
||||||
|
return c;
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
@@ -2032,7 +2038,7 @@ line:
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
exp:
|
exp:
|
||||||
NUM @{ $$ = $1; @}
|
NUM
|
||||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||||
@@ -2212,7 +2218,7 @@ line:
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
exp:
|
exp:
|
||||||
NUM @{ $$ = $1; @}
|
NUM
|
||||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||||
@@ -2417,8 +2423,8 @@ Here are the C and Bison declarations for the multi-function calculator.
|
|||||||
@end group
|
@end group
|
||||||
|
|
||||||
%define api.value.type union /* Generate YYSTYPE from these types: */
|
%define api.value.type union /* Generate YYSTYPE from these types: */
|
||||||
%token <double> NUM /* Simple double precision number. */
|
%token <double> NUM /* Double precision number. */
|
||||||
%token <symrec*> VAR FNCT /* Symbol table pointer: variable and function. */
|
%token <symrec*> VAR FUN /* Symbol table pointer: variable/function. */
|
||||||
%type <double> exp
|
%type <double> exp
|
||||||
|
|
||||||
@group
|
@group
|
||||||
@@ -2441,7 +2447,7 @@ store these values.
|
|||||||
|
|
||||||
Since values can now have various types, it is necessary to associate a type
|
Since values can now have various types, it is necessary to associate a type
|
||||||
with each grammar symbol whose semantic value is used. These symbols are
|
with each grammar symbol whose semantic value is used. These symbols are
|
||||||
@code{NUM}, @code{VAR}, @code{FNCT}, and @code{exp}. Their declarations are
|
@code{NUM}, @code{VAR}, @code{FUN}, and @code{exp}. Their declarations are
|
||||||
augmented with their data type (placed between angle brackets). For
|
augmented with their data type (placed between angle brackets). For
|
||||||
instance, values of @code{NUM} are stored in @code{double}.
|
instance, values of @code{NUM} are stored in @code{double}.
|
||||||
|
|
||||||
@@ -2457,7 +2463,7 @@ declared explicitly so we can specify its value type. @xref{Type Decl,
|
|||||||
|
|
||||||
Here are the grammar rules for the multi-function calculator.
|
Here are the grammar rules for the multi-function calculator.
|
||||||
Most of them are copied directly from @code{calc}; three rules,
|
Most of them are copied directly from @code{calc}; three rules,
|
||||||
those which mention @code{VAR} or @code{FNCT}, are new.
|
those which mention @code{VAR} or @code{FUN}, are new.
|
||||||
|
|
||||||
@comment file: mfcalc.y: 3
|
@comment file: mfcalc.y: 3
|
||||||
@example
|
@example
|
||||||
@@ -2479,10 +2485,10 @@ line:
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
exp:
|
exp:
|
||||||
NUM @{ $$ = $1; @}
|
NUM
|
||||||
| 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); @}
|
| FUN '(' exp ')' @{ $$ = $1->value.fun ($3); @}
|
||||||
| exp '+' exp @{ $$ = $1 + $3; @}
|
| exp '+' exp @{ $$ = $1 + $3; @}
|
||||||
| exp '-' exp @{ $$ = $1 - $3; @}
|
| exp '-' exp @{ $$ = $1 - $3; @}
|
||||||
| exp '*' exp @{ $$ = $1 * $3; @}
|
| exp '*' exp @{ $$ = $1 * $3; @}
|
||||||
@@ -2513,7 +2519,7 @@ provides for either functions or variables to be placed in the table.
|
|||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
/* Function type. */
|
/* Function type. */
|
||||||
typedef double (*func_t) (double);
|
typedef double (func_t) (double);
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
@@ -2521,11 +2527,11 @@ typedef double (*func_t) (double);
|
|||||||
struct symrec
|
struct symrec
|
||||||
@{
|
@{
|
||||||
char *name; /* name of symbol */
|
char *name; /* name of symbol */
|
||||||
int type; /* type of symbol: either VAR or FNCT */
|
int type; /* type of symbol: either VAR or FUN */
|
||||||
union
|
union
|
||||||
@{
|
@{
|
||||||
double var; /* value of a VAR */
|
double var; /* value of a VAR */
|
||||||
func_t fnctptr; /* value of a FNCT */
|
func_t *fun; /* value of a FUN */
|
||||||
@} value;
|
@} value;
|
||||||
struct symrec *next; /* link field */
|
struct symrec *next; /* link field */
|
||||||
@};
|
@};
|
||||||
@@ -2537,8 +2543,8 @@ typedef struct symrec symrec;
|
|||||||
/* The symbol table: a chain of 'struct symrec'. */
|
/* The symbol table: a chain of 'struct symrec'. */
|
||||||
extern symrec *sym_table;
|
extern symrec *sym_table;
|
||||||
|
|
||||||
symrec *putsym (char const *, int);
|
symrec *putsym (char const *name, int sym_type);
|
||||||
symrec *getsym (char const *);
|
symrec *getsym (char const *name);
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -2550,13 +2556,13 @@ the symbol table:
|
|||||||
@group
|
@group
|
||||||
struct init
|
struct init
|
||||||
@{
|
@{
|
||||||
char const *fname;
|
char const *name;
|
||||||
double (*fnct) (double);
|
func_t *fun;
|
||||||
@};
|
@};
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
struct init const arith_fncts[] =
|
struct init const arith_funs[] =
|
||||||
@{
|
@{
|
||||||
@{ "atan", atan @},
|
@{ "atan", atan @},
|
||||||
@{ "cos", cos @},
|
@{ "cos", cos @},
|
||||||
@@ -2575,15 +2581,15 @@ symrec *sym_table;
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
/* Put arithmetic functions in table. */
|
/* Put arithmetic functions in table. */
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
init_table (void)
|
init_table (void)
|
||||||
|
@end group
|
||||||
|
@group
|
||||||
@{
|
@{
|
||||||
int i;
|
for (int i = 0; arith_funs[i].name; i++)
|
||||||
for (i = 0; arith_fncts[i].fname != 0; i++)
|
|
||||||
@{
|
@{
|
||||||
symrec *ptr = putsym (arith_fncts[i].fname, FNCT);
|
symrec *ptr = putsym (arith_funs[i].name, FUN);
|
||||||
ptr->value.fnctptr = arith_fncts[i].fnct;
|
ptr->value.fun = arith_funs[i].fun;
|
||||||
@}
|
@}
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
@@ -2594,7 +2600,7 @@ files, you can add additional functions to the calculator.
|
|||||||
|
|
||||||
Two important functions allow look-up and installation of symbols in the
|
Two important functions allow look-up and installation of symbols in the
|
||||||
symbol table. The function @code{putsym} is passed a name and the type
|
symbol table. The function @code{putsym} is passed a name and the type
|
||||||
(@code{VAR} or @code{FNCT}) of the object to be installed. The object is
|
(@code{VAR} or @code{FUN}) of the object to be installed. The object is
|
||||||
linked to the front of the list, and a pointer to the object is returned.
|
linked to the front of the list, and a pointer to the object is returned.
|
||||||
The function @code{getsym} is passed the name of the symbol to look up. If
|
The function @code{getsym} is passed the name of the symbol to look up. If
|
||||||
found, a pointer to that symbol is returned; otherwise zero is returned.
|
found, a pointer to that symbol is returned; otherwise zero is returned.
|
||||||
@@ -2606,29 +2612,26 @@ found, a pointer to that symbol is returned; otherwise zero is returned.
|
|||||||
|
|
||||||
@group
|
@group
|
||||||
symrec *
|
symrec *
|
||||||
putsym (char const *sym_name, int sym_type)
|
putsym (char const *name, int sym_type)
|
||||||
@{
|
@{
|
||||||
symrec *ptr = (symrec *) malloc (sizeof (symrec));
|
symrec *res = (symrec *) malloc (sizeof (symrec));
|
||||||
ptr->name = (char *) malloc (strlen (sym_name) + 1);
|
res->name = strdup (name);
|
||||||
strcpy (ptr->name,sym_name);
|
res->type = sym_type;
|
||||||
ptr->type = sym_type;
|
res->value.var = 0; /* Set value to 0 even if fun. */
|
||||||
ptr->value.var = 0; /* Set value to 0 even if fctn. */
|
res->next = sym_table;
|
||||||
ptr->next = (struct symrec *)sym_table;
|
sym_table = res;
|
||||||
sym_table = ptr;
|
return res;
|
||||||
return ptr;
|
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
symrec *
|
symrec *
|
||||||
getsym (char const *sym_name)
|
getsym (char const *name)
|
||||||
@{
|
@{
|
||||||
symrec *ptr;
|
for (symrec *p = sym_table; p; p = p->next)
|
||||||
for (ptr = sym_table; ptr != (symrec *) 0;
|
if (strcmp (p->name, name) == 0)
|
||||||
ptr = (symrec *)ptr->next)
|
return p;
|
||||||
if (strcmp (ptr->name, sym_name) == 0)
|
return NULL;
|
||||||
return ptr;
|
|
||||||
return 0;
|
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
@end example
|
@end example
|
||||||
@@ -2643,7 +2646,7 @@ functions depending on what the symbol table says about them.
|
|||||||
|
|
||||||
The string is passed to @code{getsym} for look up in the symbol table. If
|
The string is passed to @code{getsym} for look up in the symbol table. If
|
||||||
the name appears in the table, a pointer to its location and its type
|
the name appears in the table, a pointer to its location and its type
|
||||||
(@code{VAR} or @code{FNCT}) is returned to @code{yyparse}. If it is not
|
(@code{VAR} or @code{FUN}) is returned to @code{yyparse}. If it is not
|
||||||
already in the table, then it is installed as a @code{VAR} using
|
already in the table, then it is installed as a @code{VAR} using
|
||||||
@code{putsym}. Again, a pointer and its type (which must be @code{VAR}) is
|
@code{putsym}. Again, a pointer and its type (which must be @code{VAR}) is
|
||||||
returned to @code{yyparse}.
|
returned to @code{yyparse}.
|
||||||
@@ -2694,13 +2697,11 @@ Bison generated a definition of @code{YYSTYPE} with a member named
|
|||||||
for a 40-character symbol name. */
|
for a 40-character symbol name. */
|
||||||
static size_t length = 40;
|
static size_t length = 40;
|
||||||
static char *symbuf = 0;
|
static char *symbuf = 0;
|
||||||
symrec *s;
|
|
||||||
int i;
|
|
||||||
@end group
|
@end group
|
||||||
if (!symbuf)
|
if (!symbuf)
|
||||||
symbuf = (char *) malloc (length + 1);
|
symbuf = malloc (length + 1);
|
||||||
|
|
||||||
i = 0;
|
int i = 0;
|
||||||
do
|
do
|
||||||
@group
|
@group
|
||||||
@{
|
@{
|
||||||
@@ -2708,7 +2709,7 @@ Bison generated a definition of @code{YYSTYPE} with a member named
|
|||||||
if (i == length)
|
if (i == length)
|
||||||
@{
|
@{
|
||||||
length *= 2;
|
length *= 2;
|
||||||
symbuf = (char *) realloc (symbuf, length + 1);
|
symbuf = realloc (symbuf, length + 1);
|
||||||
@}
|
@}
|
||||||
/* Add this character to the buffer. */
|
/* Add this character to the buffer. */
|
||||||
symbuf[i++] = c;
|
symbuf[i++] = c;
|
||||||
@@ -2724,10 +2725,10 @@ Bison generated a definition of @code{YYSTYPE} with a member named
|
|||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
s = getsym (symbuf);
|
symrec *s = getsym (symbuf);
|
||||||
if (s == 0)
|
if (!s)
|
||||||
s = putsym (symbuf, VAR);
|
s = putsym (symbuf, VAR);
|
||||||
*((symrec**) &yylval) = s;
|
yylval.VAR = s; /* or yylval.FUN = s. */
|
||||||
return s->type;
|
return s->type;
|
||||||
@}
|
@}
|
||||||
|
|
||||||
@@ -2748,22 +2749,22 @@ on user demand (@xref{Tracing, , Tracing Your Parser}, for details):
|
|||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
/* Called by yyparse on error. */
|
/* Called by yyparse on error. */
|
||||||
void
|
void yyerror (char const *s)
|
||||||
yyerror (char const *s)
|
|
||||||
@{
|
@{
|
||||||
fprintf (stderr, "%s\n", s);
|
fprintf (stderr, "%s\n", s);
|
||||||
@}
|
@}
|
||||||
@end group
|
@end group
|
||||||
|
|
||||||
@group
|
@group
|
||||||
int
|
int main (int argc, char const* argv[])
|
||||||
main (int argc, char const* argv[])
|
@end group
|
||||||
|
@group
|
||||||
@{
|
@{
|
||||||
int i;
|
|
||||||
/* Enable parse traces on option -p. */
|
/* Enable parse traces on option -p. */
|
||||||
for (i = 1; i < argc; ++i)
|
if (argc == 2 && strcmp(argv[1], "-p") == 0)
|
||||||
if (!strcmp(argv[i], "-p"))
|
yydebug = 1;
|
||||||
yydebug = 1;
|
@end group
|
||||||
|
@group
|
||||||
init_table ();
|
init_table ();
|
||||||
return yyparse ();
|
return yyparse ();
|
||||||
@}
|
@}
|
||||||
@@ -7011,9 +7012,9 @@ assuming that the characters of the token are stored in
|
|||||||
characters like @samp{"} that require escaping.
|
characters like @samp{"} that require escaping.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
for (i = 0; i < YYNTOKENS; i++)
|
for (int i = 0; i < YYNTOKENS; i++)
|
||||||
@{
|
@{
|
||||||
if (yytname[i] != 0
|
if (yytname[i]
|
||||||
&& yytname[i][0] == '"'
|
&& yytname[i][0] == '"'
|
||||||
&& ! strncmp (yytname[i] + 1, token_buffer,
|
&& ! strncmp (yytname[i] + 1, token_buffer,
|
||||||
strlen (token_buffer))
|
strlen (token_buffer))
|
||||||
@@ -10002,7 +10003,7 @@ prologue:
|
|||||||
|
|
||||||
/* Formatting semantic values. */
|
/* Formatting semantic values. */
|
||||||
%printer @{ fprintf (yyo, "%s", $$->name); @} VAR;
|
%printer @{ fprintf (yyo, "%s", $$->name); @} VAR;
|
||||||
%printer @{ fprintf (yyo, "%s()", $$->name); @} FNCT;
|
%printer @{ fprintf (yyo, "%s()", $$->name); @} FUN;
|
||||||
%printer @{ fprintf (yyo, "%g", $$); @} <double>;
|
%printer @{ fprintf (yyo, "%g", $$); @} <double>;
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@@ -10015,7 +10016,7 @@ ill-named) @code{%verbose} directive.
|
|||||||
|
|
||||||
The set of @code{%printer} directives demonstrates how to format the
|
The set of @code{%printer} directives demonstrates how to format the
|
||||||
semantic value in the traces. Note that the specification can be done
|
semantic value in the traces. Note that the specification can be done
|
||||||
either on the symbol type (e.g., @code{VAR} or @code{FNCT}), or on the type
|
either on the symbol type (e.g., @code{VAR} or @code{FUN}), or on the type
|
||||||
tag: since @code{<double>} is the type for both @code{NUM} and @code{exp},
|
tag: since @code{<double>} is the type for both @code{NUM} and @code{exp},
|
||||||
this printer will be used for them.
|
this printer will be used for them.
|
||||||
|
|
||||||
@@ -10040,13 +10041,13 @@ a valueless (@samp{()}) @code{input} nonterminal (@code{nterm}).
|
|||||||
|
|
||||||
Then the parser calls the scanner.
|
Then the parser calls the scanner.
|
||||||
@example
|
@example
|
||||||
Reading a token: Next token is token FNCT (sin())
|
Reading a token: Next token is token FUN (sin())
|
||||||
Shifting token FNCT (sin())
|
Shifting token FUN (sin())
|
||||||
Entering state 6
|
Entering state 6
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
That token (@code{token}) is a function (@code{FNCT}) whose value is
|
That token (@code{token}) is a function (@code{FUN}) whose value is
|
||||||
@samp{sin} as formatted per our @code{%printer} specification: @samp{sin()}.
|
@samp{sin} as formatted per our @code{%printer} specification: @samp{sin()}.
|
||||||
The parser stores (@code{Shifting}) that token, and others, until it can do
|
The parser stores (@code{Shifting}) that token, and others, until it can do
|
||||||
something about it.
|
something about it.
|
||||||
@@ -10101,7 +10102,7 @@ Next token is token ')' ()
|
|||||||
Shifting token ')' ()
|
Shifting token ')' ()
|
||||||
Entering state 31
|
Entering state 31
|
||||||
Reducing stack by rule 9 (line 47):
|
Reducing stack by rule 9 (line 47):
|
||||||
$1 = token FNCT (sin())
|
$1 = token FUN (sin())
|
||||||
$2 = token '(' ()
|
$2 = token '(' ()
|
||||||
$3 = nterm exp (0.000000)
|
$3 = nterm exp (0.000000)
|
||||||
$4 = token ')' ()
|
$4 = token ')' ()
|
||||||
@@ -14226,8 +14227,8 @@ London, Department of Computer Science, TR-00-12 (December 2000).
|
|||||||
@c LocalWords: NUM exp subsubsection kbd Ctrl ctype EOF getchar isdigit nonfree
|
@c LocalWords: NUM exp subsubsection kbd Ctrl ctype EOF getchar isdigit nonfree
|
||||||
@c LocalWords: ungetc stdin scanf sc calc ulator ls lm cc NEG prec yyerrok rr
|
@c LocalWords: ungetc stdin scanf sc calc ulator ls lm cc NEG prec yyerrok rr
|
||||||
@c LocalWords: longjmp fprintf stderr yylloc YYLTYPE cos ln Stallman Destructor
|
@c LocalWords: longjmp fprintf stderr yylloc YYLTYPE cos ln Stallman Destructor
|
||||||
@c LocalWords: symrec val tptr FNCT fnctptr func struct sym enum IEC syntaxes
|
@c LocalWords: symrec val tptr FUN func struct sym enum IEC syntaxes
|
||||||
@c LocalWords: fnct putsym getsym fname arith fncts atan ptr malloc sizeof Lex
|
@c LocalWords: fun putsym getsym arith funs atan ptr malloc sizeof Lex
|
||||||
@c LocalWords: strlen strcpy fctn strcmp isalpha symbuf realloc isalnum DOTDOT
|
@c LocalWords: strlen strcpy fctn strcmp isalpha symbuf realloc isalnum DOTDOT
|
||||||
@c LocalWords: ptypes itype YYPRINT trigraphs yytname expseq vindex dtype Unary
|
@c LocalWords: ptypes itype YYPRINT trigraphs yytname expseq vindex dtype Unary
|
||||||
@c LocalWords: Rhs YYRHSLOC LE nonassoc op deffn typeless yynerrs nonterminal
|
@c LocalWords: Rhs YYRHSLOC LE nonassoc op deffn typeless yynerrs nonterminal
|
||||||
|
|||||||
Reference in New Issue
Block a user