22.10.2013 Views

4 - Forth Interest Group

4 - Forth Interest Group

4 - Forth Interest Group

SHOW MORE
SHOW LESS

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 '

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!