.\" @(#)ssA 6.1 (Berkeley) 5/8/86
This section discusses a number of advanced features
Simulating Error and Accept in Actions
The parsing actions of error and accept can be simulated
in an action by use of macros YYACCEPT and YYERROR.
the parser to behave as if the current input symbol
is called, and error recovery takes place.
These mechanisms can be used to simulate parsers
with multiple endmarkers or context-sensitive syntax checking.
Accessing Values in Enclosing Rules.
An action may refer to values
returned by actions to the left of the current rule.
The mechanism is simply the same as with ordinary actions,
a dollar sign followed by a digit, but in this case the
digit may be 0 or negative.
sent : adj noun verb adj noun
{ \fIlook at the sentence\fR . . . }
In the action following the word CRONE, a check is made that the
preceding token shifted was not YOUNG.
Obviously, this is only possible when a great deal is known about
what might precede the symbol
There is also a distinctly unstructured flavor about this.
Nevertheless, at times this mechanism will save a great
deal of trouble, especially when a few combinations are to
be excluded from an otherwise regular structure.
Support for Arbitrary Value Types
By default, the values returned by actions and the lexical analyzer are integers.
values of other types, including structures.
In addition, Yacc keeps track of the types, and inserts
appropriate union member names so that the resulting parser will
be strictly type checked.
The Yacc value stack (see Section 4)
of the various types of values desired.
The user declares the union, and associates union member names
to each token and nonterminal symbol having a value.
When the value is referenced through a $$ or $n construction,
Yacc will automatically insert the appropriate union name, so that
no unwanted conversions will take place.
In addition, type checking commands such as
Johnson Lint Checker 1273
There are three mechanisms used to provide for this typing.
First, there is a way of defining the union; this must be
done by the user since other programs, notably the lexical analyzer,
must know about the union member names.
Second, there is a way of associating a union member name with tokens
Finally, there is a mechanism for describing the type of those
few values where Yacc can not easily determine the type.
To declare the union, the user includes in the declaration section:
This declares the Yacc value stack,
and the external variables
to have type equal to this union.
If Yacc was invoked with the
option, the union declaration
the union may be declared in a header file, and a typedef
used to define the variable YYSTYPE to represent
Thus, the header file might also have said:
The header file must be included in the declarations
section, by use of %{ and %}.
the union member names must be associated
with the various terminal and nonterminal names.
is used to indicate a union member name.
%left, %right, and %nonassoc,
the union member name is associated with the tokens listed.
%left <optype> \'+\' \'\-\'
will cause any reference to values returned by these two tokens to be
Another keyword, %type, is
used similarly to associate
union member names with nonterminals.
%type <nodetype> expr stat
There remain a couple of cases where these mechanisms are insufficient.
If there is an action within a rule, the value returned
Similarly, reference to left context values (such as $0 \- see the
previous subsection ) leaves Yacc with no easy way of knowing the type.
In this case, a type can be imposed on the reference by inserting
a union member name, between < and >, immediately after
An example of this usage is
rule : aaa { $<intval>$ = 3; } bbb
{ fun( $<intval>2, $<other>0 ); }
This syntax has little to recommend it, but the situation arises rarely.
A sample specification is given in Appendix C.
The facilities in this subsection are not triggered until they are used:
in particular, the use of %type will turn on these mechanisms.
When they are used, there is a fairly strict level of checking.
For example, use of $n or $$ to refer to something with no defined type
If these facilities are not triggered, the Yacc value stack is used to
as was true historically.