parser.y 4.86 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
%{

#include <iostream>
#include "node.hpp"

extern int yylex();
void yyerror(const char *s) {
	std::cerr << "ERROR: " << s << std::endl;
}

11 12 13
// our root node ;)
Node *rootNode;

14 15 16 17
// a very dirty hack for the sake of readibility...
template<typename T>
std::unique_ptr<T> UNIQUE(T *ptr) { return std::unique_ptr<T>(ptr); }

18 19 20 21 22
%}


%union {
	std::string *str;
23 24
	int token;

25 26
	Node *node;
	NExpression *expr;
27
	NBinaryOperator *cond;
28 29
	NInteger *integer;
	NIdentifier *ident;
30
	NBitfieldVariable *var;
31 32 33 34 35 36 37

	NItemSequence *itemseq;
	NItem *item;
	NState *state;
	NStateSequence *stateseq;
	NStatement *stmt;
	NStatementSequence *stmtseq;
38 39
	NWhen *when;
	NWhenSequence *whenseq;
40 41 42 43
}


%token <str>	TOK_ID TOK_INT
44 45

/* binary operators */
46
%token <token>	TOK_PLUS TOK_MINUS TOK_MUL TOK_DIV TOK_AND TOK_OR
47
%token <token>	TOK_LSHIFT TOK_RSHIFT
48

49 50 51 52 53 54 55 56 57
/* comparison operators (binary) */
%token <token>	TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE

/* other operators (~ and !) */
%token <token>	TOK_INV TOK_NOT

/* separators... */
%token <token>	TOK_LBRAC TOK_RBRAC TOK_LPAR TOK_RPAR
%token <token>	TOK_COLUMN
58

59 60 61 62 63 64 65
/* language keywords */
%token <token>	TOK_AUTO TOK_REG TOK_VAR TOK_CONST TOK_SIGNAL
%token <token>	TOK_STATE TOK_WHEN TOK_EXIT TOK_GOTO
%token <token>	TOK_IF TOK_THEN TOK_ELSE TOK_END


/* non-terminal types */
66
%type <expr> expr
67 68
%type <ident> ident
%type <integer> literal
69
%type <var> variable
70 71 72 73 74 75 76

%type <itemseq> items
%type <item> item
%type <stmtseq> stmts
%type <stmt> stmt
%type <stateseq> states
%type <state> state
77 78 79 80 81
%type <when> when
%type <whenseq> whens

/* may change later */
%type <cond> cond
82 83


84 85
/*%type <token> unop
%type <token> binop*/
86
%type <token> compop
87 88


89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/* precedence to solve shift/reduce conflicts explicitly */
%precedence TOK_THEN
%precedence TOK_ELSE


/* operator associativity to avoid shift/reduce conflicts */
/*
%left TOK_OR
%left TOK_AND
%left TOK_LSHIFT TOK_RSHIFT
%left TOK_PLUS TOK_MINUS
%left TOK_MUL TOK_DIV
*/
%left TOK_OR TOK_AND TOK_LSHIFT TOK_RSHIFT TOK_PLUS TOK_MINUS TOK_MUL TOK_DIV ANY_BINOP
%type <token> binop
%type <token> unop

%right UNARY_MINUS

108

109
%start program
110 111 112 113

%%


114 115 116
program : items { rootNode = $1; }
	 ;

117 118
items : items item { $1->addItem(UNIQUE($2)); $$ = $1; }
	 | item { $$ = new NItemSequence(UNIQUE($1)); }
119
	 ;
120

121
item : TOK_REG ident TOK_EQ literal { $$ = new NRegItem(UNIQUE($2), UNIQUE($4)); }
122
	/* TODO var const signal*/
123 124
	| TOK_VAR ident { $$ = new NVarItem(UNIQUE($2)); }
	| TOK_CONST ident TOK_EQ literal { $$ = new NConstItem(UNIQUE($2), UNIQUE($4)); }
125
	| TOK_SIGNAL ident TOK_EQ ident TOK_LBRAC expr TOK_RBRAC
126
		{ $$ = new NSignalItem(UNIQUE($2), UNIQUE($4), UNIQUE($6), false); }
127
	| TOK_SIGNAL ident TOK_EQ TOK_NOT ident TOK_LBRAC expr TOK_RBRAC
128
		{ $$ = new NSignalItem(UNIQUE($2), UNIQUE($5), UNIQUE($7), true); }
129
	| TOK_AUTO ident stmts states state {
130 131
		$4->addItem(UNIQUE($5));
		$$ = new NAutoItem(UNIQUE($2), UNIQUE($3), UNIQUE($4));
132 133 134 135
	}
	;

/* zero or more statements */
136
stmts : stmts stmt { $1->addItem(UNIQUE($2)); }
137 138 139
	  | { $$ = new NStatementSequence(); }
	  ;

140 141
stmt : variable TOK_EQ expr { $$ = new NAssignStatement(UNIQUE($1), UNIQUE($3)); }
	 | TOK_GOTO ident { $$ = new NGotoStatement(UNIQUE($2)); }
142
	 | TOK_EXIT { $$ = new NExitStatement(); }
143
	 | TOK_IF cond TOK_THEN stmts stmt TOK_END {
144 145
			$4->addItem(UNIQUE($5));
			$$ = new NIfStatement(UNIQUE($2), UNIQUE($4));
146 147
		}
	 | TOK_IF cond TOK_THEN stmts stmt TOK_ELSE stmts stmt TOK_END {
148 149 150
			$4->addItem(UNIQUE($5));
			$7->addItem(UNIQUE($8));
			$$ = new NIfStatement(UNIQUE($2), UNIQUE($4), UNIQUE($7));
151
		}
152 153 154
	 ;

/* zero or more states */
155
states : states state { $1->addItem(UNIQUE($2)); }
156 157 158
	   | { $$ = new NStateSequence(); }
	   ;

159
state : TOK_STATE ident stmts whens when {
160 161
	  		$4->addItem(UNIQUE($5));
	  		$$ = new NState(UNIQUE($2), UNIQUE($3), UNIQUE($4));
162 163 164 165
		}
	  ;

/* zero or more whens */
166
whens : whens when { $1->addItem(UNIQUE($2)); }
167
	  | { $$ = new NWhenSequence(); }
168 169
	  ;

170
when : TOK_WHEN ident stmts stmt {
171 172
	 		$3->addItem(UNIQUE($4));
			$$ = new NWhen(UNIQUE($2), UNIQUE($3));
173 174 175
	 }
	 ;

176 177
ident : TOK_ID { $$ = new NIdentifier(*$1); delete $1; }
	  ;
178

179 180
literal : TOK_INT { $$ = new NInteger(*$1); delete $1; }
		;
181

182 183
binop : TOK_PLUS | TOK_MINUS | TOK_MUL | TOK_DIV | TOK_AND | TOK_OR
	  | TOK_LSHIFT | TOK_RSHIFT;
184

185 186 187 188
compop : TOK_EQ | TOK_NE | TOK_GT | TOK_GE | TOK_LT | TOK_LE ;

unop : TOK_MINUS | TOK_INV ;

189
variable : ident { $$ = new NBitfieldVariable(UNIQUE($1)); }
190
	 	 | ident TOK_LBRAC expr TOK_RBRAC
191
			{ $$ = new NBitfieldVariable(UNIQUE($1), UNIQUE($3)); }
192
	 	 | ident TOK_LBRAC expr TOK_COLUMN expr TOK_RBRAC
193
		 	{ $$ = new NBitfieldVariable(UNIQUE($1), UNIQUE($3), UNIQUE($5)); }
194 195
		 ;

196 197
expr : variable { $$ = $1; }
	 | literal { $$ = $1; }
198 199
	 | unop expr %prec UNARY_MINUS { $$ = new NUnaryOperator($1, UNIQUE($2)); }
	 | expr binop expr %prec ANY_BINOP { $$ = new NBinaryOperator($2, UNIQUE($1), UNIQUE($3)); }
200
	 | TOK_LPAR expr TOK_RPAR { $$ = $2; }
201
	 ;
202

203
cond : expr compop expr { $$ = new NBinaryOperator($2, UNIQUE($1), UNIQUE($3)); }
204
	 ;
205 206 207


%%