next up previous contents index
Next: Interfacing with Structure Files Up: Running It Previous: Using lint

   
Interfacing with Yacc and Lex

The first piece of advice is: try to avoid it, because the SG (SSL) structure file format is much more convenient. Notwithstanding that, it is fairly simple, and the term processor handles a lot of the machinery involved, such as defining a data type for the yacc stack. The two important considerations in using yacc are the difference between abstract syntax and concrete syntax, and handling terminal symbols with values, such as identifiers. Abstract syntax should be the input of the term processor and concrete syntax goes into yacc. First a simple abstract syntax.

/* Abstract syntax */ funnytree: Str(casestring) | Cons(funnytree funnytree) ;

In the yacc input file, concrete syntax is translated into abstract syntax using the operator functions. Note also the type annotation of concrete symbols, as in %token <yt_casestring> ID. This type is a union selector of the generated YYSTYPE.   


/* Concrete syntax */ %{ #include "k.h"
funnytree thetree; %}
%token <yt_casestring> ID
%type <yt_funnytree> tree %%
theroot:tree { thetree = $1;};
tree: ID { $$ = Str($1);} | '(' tree tree ')' { $$ = Cons($2, $3);} ;

The typical way of using lex  is to have the lexical analyser generate tokens for the parser and build values of the phylum casestring. The following is the complete lex input.   


/* Lexemes */ %{ #include "k.h" #include "y.tab.h" %} %% [a-zA-Z0-9]+ { yylval.yt_casestring = mkcasestring(yytext); return ID;} [\t\n ] { ; } /* skip the white space */ . { return yytext[0]; }


next up previous contents index
Next: Interfacing with Structure Files Up: Running It Previous: Using lint

2000-04-17