4 - Forth Interest Group
4 - Forth Interest Group
4 - Forth Interest Group
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
action is embedded in the production (like this: reduce :<br />
f oo { misc . C verbiage ) bar), the action is triggered<br />
when the token string leading up to it is seen. Notice that this<br />
will cause a reducdreduce conflict if two rules have the same<br />
viable prefut, even if the actions are identical. To get around<br />
this, split the two productions into three, and perform the<br />
action at the end of the production that is common to both<br />
of the originals. If the actions required are not identical, you<br />
either have to find some way to postpone the action to the<br />
end of the production, or you will have to use some parser<br />
generator besides yacc. For example, this:<br />
£00: footokenl { foofunc(); 1 footoken2<br />
I f ootokenl ( f oof unc ( ) ; ) f ootoken3<br />
must be rewritten as:<br />
fooprefix: footokenl { foofunc0; 1<br />
£00: fooprefix footoken2<br />
I fooprefix footoken3<br />
and this:<br />
£00: footokenl { foofuncl0; ) footoken2<br />
I footokenl I foofunc2 0 ; ) footoken3<br />
must be rewritten to move the action to the end of the<br />
productions, or at least past the point where the productions<br />
share a viable prefix.<br />
Each token in yacc can have an associated value. This<br />
value is set in the actions associated with productions for<br />
nonterminals, or the lexical analyzer for terminals. It can be<br />
accessed in a similar fashion to the arguments to macros in<br />
m4, by $ (some digit) , where the digit corresponds to the<br />
token in the production. The value is set by assigning a value<br />
to $ $ in the action corresponding to the production. Thus, this:<br />
expr: \-I expr %prec UMINUS { $$ = - $2; }<br />
would set the value of the left-hand expr to minus the righthand<br />
expr. The lexical analyzer can set a token value by<br />
assigning global yylval' The type<br />
of the values $$, $1, etc. Can either be Set by defining the<br />
YY~TYPE to something, or by the command<br />
%union in the declarations section. Since the FSAT project's<br />
C-to-<strong>Forth</strong> compiler will need to operate on strings and an<br />
associated type, I'll be using<br />
the first method, kludged to<br />
allow me to store both a string<br />
and a type value. If neither<br />
yys~yp~ is defied nor the<br />
keyword %union is used, the<br />
type will default to int.<br />
Of course, we'd be in a<br />
pretty sorry state if our compilers<br />
couldn't handle syntax errors.<br />
yacc does have a way to<br />
easily integrate error handling,<br />
however. It uses the psuedoterminalerror.<br />
error stands<br />
'<br />
Figure Three.<br />
%token INCLUDE /* #include token */<br />
%token FILENAME<br />
for any sequence of input that doesn't form a valid production<br />
in the current context. For example, since a C statement must<br />
end with a ';' character, h s production would recognize an<br />
erroneous statement:<br />
statement : error ' ; '<br />
This works by getting tokens from the lexical analyzer<br />
until the token or tokens following the psuedo-terminal<br />
error are seen. These tokens are discarded. This is very<br />
handy for resynchronizing the input stream after an error<br />
condition. Although this won't correctly handle the case<br />
described above, where the opening '