11.7. Some Samples for SFL
%{
#include "ast"
…
%}
%token TOK_DEF
%token TOK_END
%token <strval> TOK_ID
%token <intval> TOK_NUMBER
%left <intval> TOK_ADDOP
%left <intval> TOK_MULOP
/* The following are needed by
* expr : expr expr
*/
%nonassoc TOK_ID TOK_NUMBER '['
%left JUXTAPOSITION
%type <ast> expr
%type <strlist> idlist
%type <exprlist> exprlist
%%
/*-------------------------------------
* program reads all of the definitions
* and starts the interpreter.
*-------------------------------------*/
program : definitions
{runInterpreter();
}
;
/*-------------------------------------
* definitions gets all of the
* definitions and stores each into
* the symbol table.
*-------------------------------------*/
definitions: /*empty*/
{}
| definitions definition
{}
;
/*-------------------------------------
* definition matches a single
* definition, which it stores into
* the symbol table.
*-------------------------------------*/
definition : TOK_DEF idlist '=' expr TOK_END
{installDefinition($2, $4);
}
;
/*-------------------------------------
* idlist matches a sequence of
* identifiers, without any separation.
* Its attribute is a linked list of
* the identifiers backwards.
* For example, if the list is
* a b c
* then the attribute of idlist is
* ["c", "b", "a"]
*-------------------------------------*/
idlist : /* empty */
{$$ = NULL;
}
| idlist TOK_ID
{$$ = strCons($2, $1);
}
;
/*-------------------------------------
* expr matches an expression. It's
* attribute is an abstract syntax tree
* that represents the expression.
*-------------------------------------*/
expr : TOK_ID
{$$ = identifierNode($1);
}
| TOK_NUMBER
{$$ = integerConstant($1);
}
| expr expr %prec JUXTAPOSITION
{$$ = applyNode($1, $2);
}
| expr TOK_MULOP expr
{$$ = operatorNode($2, $1, $3);
}
| expr TOK_ADDOP expr
{$$ = operatorNode($2, $1, $3);
}
| '[' ']'
{$$ = emptyList();
}
| '[' exprlist ']'
{$$ = listAST($2);
}
…
;
/*-------------------------------------
* exprlist matches a list of exprs,
* separated by commas.
*
* It's attribute is a linked list of
* the ASTs for the exprs, in forward
* order.
*-------------------------------------*/
exprlist : expr
{$$ = exprCons($1, NULL);
}
| expr ',' exprlist
{$$ = exprCons($1, $3);
}
;
%%
/*-------------------------------------
* installDefinition(lhs, body)
* converts a definition into form
*
* def id = expr end
*
* and stores pair (id, expr) into the
* symbol table.
*
* For example, it converts definition
*
* def a b c = body end
*
* into
*
* def a = b -> (c -> body) end
*
* lhs is the list of ids on the
* left-hand side backwards.
* For
*
* def a b c = body end
*
* lis is ["c", "b", "a"].
*-------------------------------------*/
void installDefinition(IDLIST lhs, AST body)
{
AST newbody = body;
for(IDLIST p = lhs; p->next != NULL; p = p->next)
{
newbody = functionNode(p->item, newBody);
}
insertSymbolTable(p->item, newbody);
freelist(lhs);
}