-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.y
128 lines (97 loc) · 4.2 KB
/
parser.y
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
%{
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "parser.tab.h"
#include "ast.h"
int yylex(void);
void yyerror(const char *s);
class AstRoot* root;
%}
%define parse.error detailed
%locations
%union {
int ival;
bool bval;
char* str;
class Node* node;
class StatementNode* statement_node;
class ExpressionNode* expression_node;
class ArgsListNode* args_node;
}
%type <statement_node> statement
%type <statement_node> statements
%type <statement_node> body
%type <expression_node> expression
%type <args_node> args_list
%token <bval> TRUE FALSE
%token <ival> NUMBER
%token <str> IDENTIFIER
%token STOP
%token STATEMENT_SEPARATOR BODY_OPEN BODY_CLOSE
%token LET ASSIGN OF_TYPE RETURN
%token IF ELSE WHILE
%token FUNC
%token EQUAL NOT_EQUAL LESS_THAN MORE_THAN LESS_EQUAL MORE_EQUAL
%token LOGIC_AND LOGIC_OR LOGIC_XOR
%token PLUS MINUS
%token MULTIPLY DIVIDE MODULO
%token LOGIC_NOT
%token EOL
%token PRINT
%start program
%left STATEMENT_SEPARATOR
%left PLUS MINUS DIVIDE MULTIPLY MODULO
%left EQUAL NOT_EQUAL LESS_THAN MORE_THAN LESS_EQUAL MORE_EQUAL
%left LOGIC_AND LOGIC_OR LOGIC_XOR
%right LOGIC_NOT
%%
program:
statements { root = new AstRoot($1); /* root->print_to_console(); */ root->execute(); }
;
body:
BODY_OPEN statements BODY_CLOSE { $$ = new BodyNode($2); }
;
args_list:
args_list ',' IDENTIFIER { $$ = new ArgsListNode($3, $1); }
| IDENTIFIER { $$ = new ArgsListNode($1); }
;
statements:
statement STATEMENT_SEPARATOR statements { $$ = new MultiStatementsNode($1, $3); }
| statement STATEMENT_SEPARATOR { $$ = $1; }
;
statement:
IDENTIFIER '(' args_list ')' { $$ = new FunctionCallNode($1, $3); }
| LET IDENTIFIER ASSIGN expression { $$ = new VariableAssignmentNode(str_to_cpp($2), $4, false); }
| IDENTIFIER ASSIGN expression { $$ = new VariableAssignmentNode(str_to_cpp($1), $3, true); }
| IF expression body { $$ = new ConditionalStatementNode($2, $3, false); }
| WHILE expression body { $$ = new ConditionalStatementNode($2, $3, true); }
| FUNC IDENTIFIER '(' args_list ')' body { $$ = new FunctionDeclarationNode($2, $6, $4); }
| PRINT IDENTIFIER { $$ = new PrintNode($2); }
| RETURN expression { $$ = new ResultNode($2); }
;
expression:
'(' expression ')' { $$ = new BraceExpressionNode($2); }
| expression MULTIPLY expression { $$ = new BinaryOperationNode(ArithmeticOperation::Multiplication, $1, $3); }
| expression DIVIDE expression { $$ = new BinaryOperationNode(ArithmeticOperation::Division, $1, $3); }
| expression PLUS expression { $$ = new BinaryOperationNode(ArithmeticOperation::Addition, $1, $3); }
| expression MINUS expression { $$ = new BinaryOperationNode(ArithmeticOperation::Substraction, $1, $3); }
| expression MODULO expression { $$ = new BinaryOperationNode(ArithmeticOperation::Modulo, $1, $3); }
| expression EQUAL expression { $$ = new BinaryOperationNode(ComparisonOperation::Equality, $1, $3); }
| expression NOT_EQUAL expression { $$ = new BinaryOperationNode(ComparisonOperation::Inequality, $1, $3); }
| expression LESS_THAN expression { $$ = new BinaryOperationNode(ComparisonOperation::Less, $1, $3); }
| expression MORE_THAN expression { $$ = new BinaryOperationNode(ComparisonOperation::More, $1, $3); }
| expression LESS_EQUAL expression { $$ = new BinaryOperationNode(ComparisonOperation::LessOrEqual, $1, $3); }
| expression MORE_EQUAL expression { $$ = new BinaryOperationNode(ComparisonOperation::MoreOrEqual, $1, $3); }
| expression LOGIC_AND expression { $$ = new BinaryOperationNode(LogicOperation::And, $1, $3); }
| expression LOGIC_OR expression { $$ = new BinaryOperationNode(LogicOperation::Or, $1, $3); }
| expression LOGIC_XOR expression { $$ = new BinaryOperationNode(LogicOperation::Xor, $1, $3); }
| LOGIC_NOT expression { $$ = new UnaryOperationNode(UnaryOperation::Not, $2); }
| MINUS expression { $$ = new UnaryOperationNode(UnaryOperation::Negate, $2); }
| TRUE { $$ = new LiteralNode(Value($1)); }
| FALSE { $$ = new LiteralNode(Value($1)); }
| NUMBER { $$ = new LiteralNode(Value($1)); }
| IDENTIFIER '(' args_list ')' { $$ = new FunctionCallNode($1, $3); }
| IDENTIFIER { $$ = new VariableReferenceNode($1); }
;
%%