blob: a4499524a371e8759d169fe9311d1866e0c5af08 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
%{
#include <iostream>
#include <cstdlib>
#include "node.hpp"
// AST
NBlock *programBlock = 0;
extern int grammarlex( );
extern int grammarget_lineno( void );
void grammarerror( const char *s )
{
std::cerr << "ERROR in line " << grammarget_lineno( ) << ": " << s << std::endl;
exit( 1 );
}
%}
%union {
Node *node;
NBlock *block;
NStatement *stmt;
NExpression *expr;
NIdentifier *ident;
NVariableDeclaration *var_decl;
std::vector<NVariableDeclaration*> *vars;
std::string *string;
ExpressionList *exprs;
int token;
}
%token <string> TIDENTIFIER TINTEGER
%token <token> TLPAREN TRPAREN TLBRACE TRBRACE
%token <token> TCOMMA
%token <token> TEQUAL TMUL TPLUS
%type <block> program stmts block
%type <ident> ident
%type <expr> numeric expr
%type <stmt> stmt func_decl var_decl
%type <vars> func_decl_args
%type <exprs> call_args
%type <token> operator
%left TEQUAL
%left TPLUS
%left TMUL
%start program
%%
program : stmts { programBlock = $1; }
;
stmts : stmt { $$ = new NBlock( ); $$->m_statements.push_back( $1 ); }
| stmts stmt { $1->m_statements.push_back( $2 ); }
;
stmt : var_decl { }
| func_decl { }
| expr { $$ = new NExpressionStatement( *$1 ); }
;
func_decl : ident ident TLPAREN func_decl_args TRPAREN block
{ $$ = new NFunctionDeclaration( *$1, *$2, *$4, *$6 ); delete $4; }
;
func_decl_args : /* procedure */ { $$ = new VariableList( ); }
| var_decl { $$ = new VariableList( ); $$->push_back( $<var_decl>1 ); }
| func_decl_args TCOMMA var_decl { $1->push_back( $<var_decl>3 ); }
;
var_decl : ident ident { $$ = new NVariableDeclaration( *$1, *$2 ); }
| ident ident TEQUAL expr { $$ = new NVariableDeclaration( *$1, *$2, $4 ); }
;
expr : numeric { }
| ident { $<ident>$ = $1; }
| expr operator expr { $$ = new NBinaryOperator( *$1, $2, *$3 ); }
| ident TLPAREN call_args TRPAREN { $$ = new NFunctionCall( *$1, *$3 ); delete $3; }
;
call_args : /* no params */ { $$ = new ExpressionList( ); }
| expr { $$ = new ExpressionList( ); $$->push_back( $1 ); }
| call_args TCOMMA expr { $1->push_back( $3 ); }
;
operator : TMUL | TPLUS
;
numeric : TINTEGER { $$ = new NInteger( atoi( $1->c_str( ) ) ); delete $1; }
;
block : TLBRACE /* empty block */ TRBRACE { $$ = new NBlock( ); }
| TLBRACE stmts TRBRACE { $$ = $2; }
;
ident : TIDENTIFIER { $$ = new NIdentifier( *$1 ); delete $1; }
;
%%
|