All pastes #431334 Raw Edit

Something

public text v1 · immutable
·published 2007-04-09 16:25 UTC
rendered paste body
%{
// LSys.y generates LSys.tab.cpp & LSys.tab.hpp

#include <iostream>
#include <sstream>
#include <fstream>
#include <windows.h>
#include <boost/smart_ptr.hpp>

using namespace boost;
using namespace std;

#include "LSysNode.h"

#include "LSysLexer.h"
#include "PreProcess.h"

PreProcessor preProcessor;
LSysLexer lSysLexer(preProcessor);

#pragma warning( disable : 4065 )

void LSyserror(const char *error);
int LSyslex();


#include "LSysDef.h"
%}

%token USYMBOL LSYMBOL STRING NUMBER COMMENT AXIOM ARROW OROR ANDAND LESS GREATER ASSIGN LEQUAL GEQUAL EQUAL NEQUAL
%left OROR
%left ANDAND
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%%

lfile: declarations rulelist {
	shared_ptr<SymLFile> sym(new SymLFile());
	sym->declarations = SYM_AS<SymDeclarations>($1);
	sym->rules = SYM_AS<SymLRules>($2);
	
	// process lfile ...
	sym->DebugPrint();
	
	// evaluate debugvar
	Defines::iterator it = sym->declarations->defines.find("Debugvar");
	if (it != sym->declarations->defines.end())
	{
		EvalValue res;
		cout << "Evalulating Debugvar: ";
		it->second->Evaluate(res, sym->declarations->defines);
		switch (res.kind)
		{
		case EvalValue::kNumber:
			cout << res.d;
			break;
		case EvalValue::kString:
			cout << "\"" << res.s << "\"";
			break;
		case EvalValue::kInvalid:
			cout << "Invalid expression";
			break;
		default:
			cout << "Critical error: unknown type after evaluation";
		}
		cout << endl;
	}
	
	$$ = SYM(sym);
}

declarations: declaration {
		shared_ptr<SymDeclarations> sym(new SymDeclarations());
		sym->Declare(SYM_AS<SymDeclaration>($1));		
		$$ = SYM(sym);
	}
	| declarations declaration {
		shared_ptr<SymDeclarations> sym(SYM_AS<SymDeclarations>($1));
		sym->Declare(SYM_AS<SymDeclaration>($2));		
		$$ = $1;
	}
	;

declaration: axiom        { $$ = $1; }
	| var_declaration ';' { $$ = $1; }
	;

var_declaration: SYMBOL ASSIGN expression {
		shared_ptr<SymDeclaration> sym(new SymDeclaration());
		sym->var = SYM_AS<SymStr>($1)->val;
		sym->val = $3;
		sym->type = SymDeclaration::declConst;
		$$ = SYM(sym);
	}

axiom: AXIOM ':' modulelist ';' { 
		shared_ptr<SymDeclaration> sym(new SymDeclaration());
		sym->val = $3;
		sym->type = SymDeclaration::declAxiom;
		$$ = SYM(sym);
	}
	

rulelist: rule {
		shared_ptr<SymLRules> sym(new SymLRules());
		sym->rules.push_back(SYM_AS<SymLRule>($1));
		$$ = SYM(sym);
	}
	| rulelist rule {
		SYM_AS<SymLRules>($1)->rules.push_back(SYM_AS<SymLRule>($2));
		$$ = $1;
	}
	;

// left context of rules
rule:                 rule_sub { $$ = $1; }
	| modulelist LESS rule_sub {
		SYM_AS<SymLRule>($3)->lc = SYM_AS<SymModuleList>($1); 
		$$ = $3;	
	}                 
	;

/* TODO: add multiple rhs for stochastic systems */
rule_sub: modulelist rightcontext condition ARROW modulelist ';' {
		shared_ptr<SymLRule> sym(new SymLRule());
		sym->lhs  = SYM_AS<SymModuleList>($1);
		sym->rc   = SYM_AS<SymModuleList>($2);
		sym->cond = SYM_AS<SymBoolExpression>($3);
		sym->rhs  = SYM_AS<SymModuleList>($5);
		// read in condition
		$$ = SYM(sym);
	}


rightcontext: /* empty */ { $$ = NullSym; }
	| GREATER modulelist  { $$ = $2; }
	;

condition: { $$ = NullSym; }
	| ':' cond_expression { $$ = $2; }
	;


/* TODO: add ! (logical unary not) and maybe ^ (logical xor) */
cond_expression: cond_expression OROR cond_expression {
		shared_ptr<SymLogicalExpression> sym(new SymLogicalExpression());
		sym->lhs = SYM_AS<SymBoolExpression>($1);
		sym->op = SymLogicalExpression::opOr;
		sym->rhs = SYM_AS<SymBoolExpression>($3);
		$$ = SYM(sym);
	}
	|            cond_expression ANDAND cond_expression {
		shared_ptr<SymLogicalExpression> sym(new SymLogicalExpression());
		sym->lhs = SYM_AS<SymBoolExpression>($1);
		sym->op = SymLogicalExpression::opAnd;
		sym->rhs = SYM_AS<SymBoolExpression>($3);
		$$ = SYM(sym);
	}
	|            '(' cond_expression ')' { $$ = $2; }
	|             compare_expression     { $$ = $1; }
	;

compare_expression: expression compare_operator expression {
		shared_ptr<SymCompareExpression> sym(new SymCompareExpression());
		sym->lhs = SYM_AS<SymExpression>($1);
		switch (SYM_AS<SymSymbol>($2)->val)
		{
		case LESS:    sym->op = SymCompareExpression::opLess;    break;
		case GREATER: sym->op = SymCompareExpression::opGreater; break;
		case GEQUAL:  sym->op = SymCompareExpression::opGequal;  break;
		case LEQUAL:  sym->op = SymCompareExpression::opLequal;  break;
		case EQUAL:   sym->op = SymCompareExpression::opEqual;   break;
		case NEQUAL:  sym->op = SymCompareExpression::opNequal;  break;
		default:
			cout << "Internal compiler error: invalid compare token matched: " << SYM_AS<SymSymbol>($2)->val << endl;
		}
		sym->rhs = SYM_AS<SymExpression>($3);
		$$ = SYM(sym);
    }
	

compare_operator: LESS    { $$ = SYMSYM(LESS);    }
	|             GREATER { $$ = SYMSYM(GREATER); }
	|             GEQUAL  { $$ = SYMSYM(GEQUAL);  }
	|             LEQUAL  { $$ = SYMSYM(LEQUAL);  }
	|             EQUAL   { $$ = SYMSYM(EQUAL);   }
	|             NEQUAL  { $$ = SYMSYM(NEQUAL);  }


modulelist: module {
		// create new module list with $1 inside
		shared_ptr<SymModuleList> sym(new SymModuleList());
		sym->modules.push_back(SYM_AS<SymModuleBase>($1));
		$$ = SYM(sym);
	}
	| modulelist module {
		// append $2 to existing module list $1
		SYM_AS<SymModuleList>($1)->modules.push_back(SYM_AS<SymModuleBase>($2));
		$$ = $1;
	}
	
	| '[' modulelist ']' {
		shared_ptr<SymModuleList> sym(new SymModuleList());
		shared_ptr<SymModuleTree> symt(new SymModuleTree());
		symt->children = SYM_AS<SymModuleList>($2);
		sym->modules.push_back(symt);
		$$ = SYM(sym);
	}
	
	| modulelist '[' modulelist ']'  {
		shared_ptr<SymModuleTree> sym(new SymModuleTree());
		sym->children = SYM_AS<SymModuleList>($3);
		SYM_AS<SymModuleList>($1)->modules.push_back(sym);
		$$ = $1;
	}
	;


module:   modulename moduleparams  { 
		shared_ptr<SymModuleDef> sym(new SymModuleDef());
		sym->name = SYM_AS<SymStr>($1)->val;
		sym->type = SymModuleDef::mtModule;
		sym->params = SYM_AS<SymExpressions>($2);
		$$ = SYM(sym);
	}
	| '?' modulename moduleparams  {
		shared_ptr<SymModuleDef> sym(new SymModuleDef());
		sym->name = SYM_AS<SymStr>($2)->val;
		sym->type = SymModuleDef::mtQuery;
		sym->params = SYM_AS<SymExpressions>($3);
		$$ = SYM(sym);
	}
	;

modulename: USYMBOL { $$ = $1; }
	/* special symbols for traditional l-system fallback */
	| '+' { $$ = $1; }
	| '-' { $$ = $1; }
	;

moduleparams: /* none */  { $$ = NullSym;  }
	| '(' expressions ')' { $$ = $2; }
	;

expressions:
	| expression {
		shared_ptr<SymExpressions> sym(new SymExpressions());
		sym->expressions.push_back(SYM_AS<SymExpression>($1));
		$$ = SYM(sym);
	}
	| expressions ',' expression {
		SYM_AS<SymExpressions>($1)->expressions.push_back(SYM_AS<SymExpression>($3));
		$$ = $1;
	}
	;

expression:  expression '+' expression {
		shared_ptr<SymBinaryExpression> sym(new SymBinaryExpression());
		sym->op = SymBinaryExpression::opAdd;
		sym->lhs = SYM_AS<SymExpression>($1);
		sym->rhs = SYM_AS<SymExpression>($3);
		$$ = SYM(sym);
	}
	|        expression '-' expression {
		shared_ptr<SymBinaryExpression> sym(new SymBinaryExpression());
		sym->op = SymBinaryExpression::opSub;
		sym->lhs = SYM_AS<SymExpression>($1);
		sym->rhs = SYM_AS<SymExpression>($3);
		$$ = SYM(sym);
	}
	|        expression '*' expression {
		shared_ptr<SymBinaryExpression> sym(new SymBinaryExpression());
		sym->op = SymBinaryExpression::opMul;
		sym->lhs = SYM_AS<SymExpression>($1);
		sym->rhs = SYM_AS<SymExpression>($3);
		$$ = SYM(sym);
	}
	|        expression '/' expression {
		shared_ptr<SymBinaryExpression> sym(new SymBinaryExpression());
		sym->op = SymBinaryExpression::opDiv;
		sym->lhs = SYM_AS<SymExpression>($1);
		sym->rhs = SYM_AS<SymExpression>($3);
		$$ = SYM(sym);
	}
	|        '-' expression %prec UMINUS {
		shared_ptr<SymUnaryExpression> sym(new SymUnaryExpression());
		sym->op = SymUnaryExpression::opMinus;
		sym->rhs = SYM_AS<SymExpression>($2);
		$$ = SYM(sym);
	}
	|        '(' expression ')' { $$ = $2}
	| expressionatom {
		$$ = $1;
	}
	;


expressionatom: const_expression  { $$ = $1; }
    | SYMBOL {
		shared_ptr<SymSymbolExpAtom> sym(new SymSymbolExpAtom(SYM_AS<SymStr>($1)->val));
		$$ = SYM(sym);
    }
const_expression: NUMBER {
		shared_ptr<SymNumberExpAtom> sym(new SymNumberExpAtom(SYM_AS<SymStr>($1)->val));
		$$ = SYM(sym);
	}
	|             STRING {
		shared_ptr<SymStringExpAtom> sym(new SymStringExpAtom(SYM_AS<SymStr>($1)->val));
		$$ = SYM(sym);
	}

SYMBOL: USYMBOL | LSYMBOL

%%

#undef yylex

void LSyserror (const char *error)
{ 
	cout << "Error: " << error << " at line " << lSysLexer.lineno() << endl;
}

int LSyslex()
{ 
	return lSysLexer.yylex();
}

int main ()
{
	ifstream f("test.l");
	lSysLexer.switch_streams(&f, 0);
	yyparse();
	cin.get();
}