home services resume portfolio contact us about me


Return To Portfolio Home


%{
/*
 * Copyright (c) 1994
 */
#ifndef lint
static char rcsid[] = "@(#)$Id: parse.y,v 1.3 1994/12/02 19:10:24 ken Exp $";
static char copyright[] = "Copyright (c) 1993 All Rights Reserved";
#endif

/***********************************************************************
 * FORMULA language Parser.
 */

#include <sys/types.h>
#include <stdio.h>

#include "ctools.h"

#include "formula.h"
#include "formulaP.h"

#define YYSTYPE		union yystack

extern union yystack	yylval;

%}

/* types of the non-terminals */
%type <sym> id ids id_list
%type <expr> lval factor func expr expr1 expr2 unary_expr
%type <expr> arg_list args optexpr nullexpr expr exprlist const_array const_item
%type <value> stat stat_list if_tail

/* Definition of returned tokens from the lexical analyzer */
%token ADDOP		/* += */
%token SUBOP		/* -= */
%token MULOP		/* *= */
%token DIVOP		/* /= */
%token MODOP		/* %= */
%token OROP		/* |= */
%token ANDOP		/* &= */
%token LSHOP		/* <<= */
%token RSHOP		/* >>= */
%token XOROP		/* ^= */
%token OR		/* || */
%token AND		/* && */
%token LE		/* < */
%token GE		/* > */
%token NE		/* != */
%token EQ		/* == */
%token SHIFTL		/* >> */
%token SHIFTR		/* << */
%token PLUSPLUS		/* ++ */
%token MINUSMINUS	/* -- */

%token BIN0		/* user defined binary operator 0 */
%token BIN1		/* user defined binary operator 1 */
%token BIN2		/* user defined binary operator 2 */
%token BIN3		/* user defined binary operator 3 */
%token BIN4		/* user defined binary operator 4 */
%token BIN5		/* user defined binary operator 5 */
%token BIN6		/* user defined binary operator 6 */
%token BIN7		/* user defined binary operator 7 */
%token BIN8		/* user defined binary operator 8 */
%token BIN9		/* user defined binary operator 9 */

%token UN0		/* user defined unary operator 0 */
%token UN1		/* user defined unary operator 1 */
%token UN2		/* user defined unary operator 2 */
%token UN3		/* user defined unary operator 3 */
%token UN4		/* user defined unary operator 4 */
%token UN5		/* user defined unary operator 5 */
%token UN6		/* user defined unary operator 6 */
%token UN7		/* user defined unary operator 7 */
%token UN8		/* user defined unary operator 8 */
%token UN9		/* user defined unary operator 9 */

%token <value> NUMBER
%token <fvalue> FLOAT
%token <string> STRING
%token <sym> FUNCTION
%token <sym> PARAMETER
%token <sym> IDENTIFIER
%token <sym> VARIABLE
%token <sym> BUILTIN
%token <sym> APPFUNC
%token <sym> APPVAR
%token <sym> BIN0 BIN1 BIN2 BIN3 BIN4 BIN5 BIN6 BIN7 BIN8 BIN9
%token <sym> UN0 UN1 UN2 UN3 UN4 UN5 UN6 UN7 UN8 UN9

%token BREAK
%token CONTINUE
%token DO
%token ELSE
%token FOR
%token IF
%token RETURN
%token WHILE

%right '=' ADDOP SUBOP MULOP DIVOP MODOP OROP ANDOP LSHOP RSHOP XOROP BIN0 BIN1
%left OR
%left AND
%left '|'
%left '^'
%left '&'
%left EQ NE BIN2 BIN3 BIN4 BIN5
%left '<' LE '>' GE
%left SHIFTL SHIFTR
%left '+' '-'
%left '*' '/' '%' BIN6 BIN7 BIN8 BIN9

%start program

%%
program		: exprlist			{ gen_the_expr($1? $1 : gennumber(0)); }
		| funclist exprlist		{ gen_the_expr($2? $2 : gennumber(0)); }
		;

exprlist	: nullexpr			{ $$ = $1; }
		| exprlist ';' nullexpr		{
							if($3) {
								if($1) gen_expr($1);
								$$ = $3;
							} else
								$$ = $1;
						}
		;

nullexpr	: expr				{ $$ = $1; }
		| /* empty */			{ $$ = NULL; }
		;

funclist	: func
		| funclist func
		;

func		: IDENTIFIER id_list
						{ func_1($1,$2); }
			'{' opt_stat_list '}'
						{ func_2($1,$2); }
		;

opt_stat_list	: stat_list
		| /* empty */
		;

id_list		: '(' ids ')'	{ $$ = $2; }

		| '(' ')'
				{ $$ = NULL; }
		;

ids		: id
				{ $1->type = PARAMETER;
				  $1->u.val = 0;
				  $1->w.param = NULL;
				  $$ = $1; }

		| ids ',' id
				{ $3->type = PARAMETER;
				  $3->u.val = $1->u.val + 1;
				  $3->w.param = $1;
				  $$ = $3; }
		;

id		: PARAMETER
				{ formula_error("%s is already used as a parameter",
								$1->name); }
		| VARIABLE
				{ formula_error("%s is already a being used as a variable",
								$1->name); }
		| APPVAR
				{ formula_error("%s is already a being used as a variable",
								$1->name); }
		| IDENTIFIER
				{ $$ = $1; }
		| FUNCTION
				{ formula_error("%s is being used as a function",
								$1->name); }
		| APPFUNC
				{ formula_error("%s is being used as a function",
								$1->name); }
		;

stat		: RETURN optexpr ';'		{ gen_return($2); }
		| expr ';'			{ gen_expr($1); }
		| BREAK ';'			{ gen_break(FG.lineno); }
		| CONTINUE ';'			{ gen_continue(FG.lineno); }

		| IF '(' expr ')'
						{ $$ = gen_if1($3); }
				stat if_tail
						{ gen_if2($<value>5,$7); }

		| FOR '(' optexpr ';' optexpr ';' optexpr ')'
						{ $$ = gen1for($3,$5); }
				stat
						{ gen2for($<value>9,$7); }

		| WHILE '(' expr ')'
						{ $$ = gen1while($3); }
			stat
						{ gen2while($<value>5); }

		| DO
						{ $$ = gen_do1(); }
			stat WHILE '(' expr ')' ';'
						{ gen_do2($6,$<value>2); }

		| '{' stat_list '}'				{;}
		| '{' '}'					{;}
		| ';'						{;}
		;

if_tail		: /* empty */			{ $$ = -1; }
		| ELSE { $$ = gen_if3(); } stat
						{ $$ = $<value>2; }
		;

stat_list	: stat_list stat			{;}
		| stat					{;}
		;

optexpr		: expr			{ $$ = $1; }
		| /* empty */		{ $$ = gennumber(1); }
		;

unary_expr	: '!' unary_expr	{ $$ = genbinary(OP_NOT,NULL,$2); }
		| '-' unary_expr	{ $$ = genbinary(OP_NEG,NULL,$2); }
		| '~' unary_expr	{ $$ = genbinary(OP_BNOT,NULL,$2); }
		| UN0 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN1 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN2 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN3 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN4 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN5 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN6 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN7 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN8 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| UN9 unary_expr	{ $$ = gen_userbinary(OP_USERUNOP,$1,NULL,$2); }
		| PLUSPLUS lval		{ $$ = genbinary(OP_ADDOP,$2,gennumber(1)); }
		| MINUSMINUS lval	{ $$ = genbinary(OP_SUBOP,$2,gennumber(1)); }
		| lval PLUSPLUS
				{ $$ = genbinary(OP_PLUSPLUS,NULL,$1); }
		| lval MINUSMINUS
				{ $$ = genbinary(OP_MINUSMINUS,NULL,$1); }
		| factor		{ $$ = $1; }
		;

expr2		: expr2 OR expr2	{ $$ = genbinary(OP_OR,$1,$3); }
		| expr2 AND expr2	{ $$ = genbinary(OP_AND,$1,$3); }
		| expr2 '|' expr2	{ $$ = genbinary(OP_BOR,$1,$3); }
		| expr2 '^' expr2	{ $$ = genbinary(OP_XOR,$1,$3); }
		| expr2 '&' expr2	{ $$ = genbinary(OP_BAND,$1,$3); }
		| expr2 EQ expr2	{ $$ = genbinary(OP_EQ,$1,$3); }
		| expr2 NE expr2	{ $$ = genbinary(OP_NE,$1,$3); }
		| expr2 '>' expr2	{ $$ = genbinary(OP_GT,$1,$3); }
		| expr2 '<' expr2	{ $$ = genbinary(OP_LT,$1,$3); }
		| expr2 GE expr2	{ $$ = genbinary(OP_GE,$1,$3); }
		| expr2 LE expr2	{ $$ = genbinary(OP_LE,$1,$3); }
		| expr2 SHIFTL expr2	{ $$ = genbinary(OP_SHL,$1,$3); }
		| expr2 SHIFTR expr2	{ $$ = genbinary(OP_SHR,$1,$3); }
		| expr2 '+' expr2	{ $$ = genbinary(OP_ADD,$1,$3); }
		| expr2 '-' expr2	{ $$ = genbinary(OP_SUB,$1,$3); }
		| expr2 '%' expr2	{ $$ = genbinary(OP_MOD,$1,$3); }
		| expr2 '*' expr2	{ $$ = genbinary(OP_MUL,$1,$3); }
		| expr2 '/' expr2	{ $$ = genbinary(OP_DIV,$1,$3); }
		| expr2 BIN0 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN1 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN2 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN3 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN4 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN5 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN6 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN7 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN8 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| expr2 BIN9 expr2	{ $$ = gen_userbinary(OP_USERBINOP,$2,$1,$3); }
		| unary_expr		{ $$ = $1; }
		;

expr1		: expr2 '?' expr1 ':' expr1	{ $$ = gentrinary($1,$3,$5); }
		| expr2				{ $$ = $1; }
		;

expr		: lval '=' expr		{ $$ = genbinary(OP_ASSIGN,$1,$3); }
		| lval ADDOP expr	{ $$ = genbinary(OP_ADDOP,$1,$3); }
		| lval SUBOP expr	{ $$ = genbinary(OP_SUBOP,$1,$3); }
		| lval MULOP expr	{ $$ = genbinary(OP_MULOP,$1,$3); }
		| lval DIVOP expr	{ $$ = genbinary(OP_DIVOP,$1,$3); }
		| lval MODOP expr	{ $$ = genbinary(OP_MODOP,$1,$3); }
		| lval RSHOP expr	{ $$ = genbinary(OP_RSHOP,$1,$3); }
		| lval LSHOP expr	{ $$ = genbinary(OP_LSHOP,$1,$3); }
		| lval OROP expr	{ $$ = genbinary(OP_OROP,$1,$3); }
		| lval ANDOP expr	{ $$ = genbinary(OP_ANDOP,$1,$3); }
		| lval XOROP expr	{ $$ = genbinary(OP_XOROP,$1,$3); }
		| expr1			{ $$ = $1; }
		;

lval		: VARIABLE			{ $$ = genvar($1,NULL); }
		| VARIABLE '[' expr ']'		{ $$ = genvar($1,$3); }
		| PARAMETER			{ $$ = genparam($1,NULL); }
		| PARAMETER '[' expr ']'	{ $$ = genparam($1,$3); }
		| APPVAR			{ $$ = genappvar($1,NULL); }
		| APPVAR '[' expr ']'		{ $$ = genappvar($1,$3); }
		| IDENTIFIER			{ $$ = genident($1,NULL); }
		| IDENTIFIER '[' expr ']'	{ $$ = genident($1,$3); }
		;

factor		: '(' expr ')'			{ $$ = $2; }
		| STRING			{ $$ = genstring($1); }
		| NUMBER			{ $$ = gennumber($1); }
		| FLOAT				{ $$ = genfloat($1); }
		| lval				{ $$ = $1; }
		| FUNCTION arg_list		{ $$ = genfunc($1,$2); }
		| BUILTIN arg_list		{ $$ = genbuiltin($1,$2); }
		| APPFUNC arg_list		{ $$ = genappfunc($1,$2); }
		| '[' const_array ']'		{ $$ = $2; }
		;

const_item	: STRING			{ $$ = genstring($1); }
		| NUMBER			{ $$ = gennumber($1); }
		| FLOAT				{ $$ = genfloat($1); }
		| '-' NUMBER			{ $$ = gennumber(-$2); }
		| '-' FLOAT			{ $$ = genfloat(-$2); }
		;

const_array	: const_item			{ $$ = genconstarray(NULL,$1); }
		| const_array ',' const_item	{ $$ = genconstarray($1,$3); }

arg_list	: '(' args ')'			{ $$ = $2; }
		| '(' ')'			{ $$ = NULL; }
		| /* empty */			{ $$ = NULL; }
		;

args		: expr				{ $$ = genargs(NULL,$1); }
		| args ',' expr			{ $$ = genargs($1,$3); }
		;

%%

/* yyerror -
 *	Pass control to the "real" error function.
 */

static void yyerror(s)
char *s;
{
	formula_error(s);
}

Return To Portfolio Home

compilers • parsers • translators • C++ • yacc &bull lex • bison • unix • windows • eiffel • grammars