-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.bison
108 lines (93 loc) · 3.36 KB
/
parser.bison
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
//Tokens
%token FMAIN LBRACKET RBRACKET
%token INT VARIABLE TRUE FALSE
%token IF ELSE ELSEIF FOR
%token LPARENTH RPARENTH DOTCOMA
%token SPRINT SSCAN
// Operator associativity & precedence
%left SUM SUB
%left MUL DIV MODUL
%left GT LT GET LET DIF COMP
%left AND OR NOT
%left ATRIB
// Root-level grammar symbol
%start program;
// Types/values in association to grammar symbols.
%union{
int INT;
char* identifier;
Expr* expr;
Command* cmd;
CommandList* cmdLst;
}
%type<INT> INT
%type<identifier> VARIABLE
%type<expr> Expr
%type<expr> BoolExpr
%type<cmd> cmd
%type<cmd> ifs
%type<cmd> atrib
%type<cmdLst> CommandList
// Use "%code requires" to make declarations go
// into both parser.c and parser.h
%code requires{
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"
extern int yylex();
extern int yyline;
extern char* yytext;
extern FILE* yyin;
extern void yyerror(const char* msg);
CommandList* root;
}
%%
program: FMAIN LBRACKET CommandList RBRACKET {root = $3;}
;
CommandList:
cmd {$$ = ast_CommandList($1,NULL);}
| cmd CommandList {$$ = ast_CommandList($1,$2);}
;
cmd: atrib
| IF BoolExpr LBRACKET CommandList ifs {$$ = ast_ifs($2,$4,$5);}
| FOR BoolExpr LBRACKET CommandList RBRACKET {$$ = ast_while($2,$4);}
| SPRINT Expr RPARENTH DOTCOMA {$$ = ast_disp($2);}
| SSCAN VARIABLE RPARENTH DOTCOMA {$$ = ast_inp($2);}
| FOR atrib BoolExpr DOTCOMA Expr LBRACKET CommandList RBRACKET {$$ = ast_for($2,$3,$5,$7);}
;
atrib: VARIABLE ATRIB Expr DOTCOMA {$$ = ast_atrib($1,$3);}
;
ifs: RBRACKET ELSEIF BoolExpr LBRACKET CommandList ifs { $$ = ast_ifs($3, $5, $6); }
| RBRACKET ELSE LBRACKET CommandList RBRACKET { $$ = ast_elses($4); }
| RBRACKET { $$ = NULL; }
;
Expr:
INT {$$ = ast_integer($1);}
| VARIABLE {$$ = ast_variable($1);}
| LPARENTH Expr RPARENTH {$$ = $2;}
| Expr SUM Expr {$$ = ast_operation($1,SUM,$3);}
| Expr SUB Expr {$$ = ast_operation($1,SUB,$3);}
| Expr MUL Expr {$$ = ast_operation($1,MUL,$3);}
| Expr DIV Expr {$$ = ast_operation($1,DIV,$3);}
| Expr MODUL Expr {$$ = ast_operation($1,MODUL,$3);}
;
BoolExpr:
TRUE {$$ = ast_integer(1);}
| FALSE {$$ = ast_integer(0);}
| LPARENTH BoolExpr RPARENTH {$$ = $2;}
| Expr GET Expr {$$ = ast_operation($1,GET,$3);}
| Expr LET Expr {$$ = ast_operation($1,LET,$3);}
| Expr LT Expr {$$ = ast_operation($1,LT,$3);}
| Expr GT Expr {$$ = ast_operation($1,GT,$3);}
| Expr DIF Expr {$$ = ast_operation($1,DIF,$3);}
| Expr COMP Expr {$$ = ast_operation($1,COMP,$3);}
| BoolExpr DIF BoolExpr {$$ = ast_operation($1,DIF,$3);}
| BoolExpr COMP BoolExpr {$$ = ast_operation($1,COMP,$3);}
| BoolExpr AND BoolExpr {$$ = ast_operation($1,AND,$3);}
| BoolExpr OR BoolExpr {$$ = ast_operation($1,OR,$3);}
| NOT BoolExpr {$$ = ast_operation($2,NOT,$2);}
;
%%
void yyerror(const char* err) {
printf("Line %d: %s - '%s'\n", yyline, err, yytext );
}