-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.mly
91 lines (78 loc) · 2.12 KB
/
parser.mly
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
(* Tabs with 4 spaces were used *)
%{
open Ast
%}
%token <Ast.constant> CST
%token <string> VARN
%token LESSER GREATER GREATEREQ LESSEREQ EQ NEQ EQEQ
%token PLUS MINUS TIMES DIV POW FACT DEC INC MOD
%token AND OR NOT
%token IF THEN ELSE DEFINE PRINT
/* ( ) , { } ; */
%token LP RP COMMA LB RB SEMICOLON
%token FUNC
%token EOF
%left LESSER GREATER GREATEREQ LESSEREQ NEQ EQEQ
%left OR AND
%right NOT
%left PLUS MINUS
%left TIMES DIV
%left POW MOD
%left FACT DEC INC
%right EQ
%nonassoc uminus
%start prog
%type <Ast.prog> prog
%%
prog:
| p = stmts EOF { List.rev p }
;
/* stmts: s = separated_list(SEMICOLON, stmt) { s } */
stmts:
i = stmt { [i] }
| l = stmts SEMICOLON i = stmt { i :: l }
;
expr:
c = CST { Econst c }
| id = VARN { Evar id }
| e1 = expr o = bop e2 = expr { Ebinop (e1, o, e2) }
| e = expr o = uop { Eunop (o, e1) }
| NOT e = expr { Eunop (NOT, e) }
| MINUS e = expr %prec uminus { Ebinop (Cst 0, Sub, e) }
| DEFINE id = VARN EQ e = expr { Define (id, e) }
| LP e = expr RP { e }
;
/* created seperatly for readablility */
func: FUNC fname = VARN LP x = separated_list(COMMA, VARN) RP LB s = stmts RB
{ Func(f, x, s) }
;
stmt:
PRINT e = expr { Print e }
| IF e = expr THEN LP s = stmts RP { Ift(e, List.rev s) }
| IF e = expr THEN LP s1 = stmts RP ELSE LP s2 = stmts RP { Ifte(e, List.rev s1, List.rev s2) }
| f = func { f }
| f = VARN LP e = separated_list(COMMA, expr) RP { Ecall (f, e) }
| LP e = expr RP { Eval e }
;
%inline bop:
| PLUS { Badd }
| MINUS { Bsub }
| TIMES { Bmul }
| DIV { Bdiv }
| AND { Band } (* && and *)
| OR { Bor } (* || or *)
| GREATER { Bgreater } (*maior do que > *)
| LESSER { Blesser } (*menor do que < *)
| GREATEREQ { BgreaterEq } (*maior do que >= *)
| LESSEREQ { BlesserEq } (*menor do que <= *)
| EQEQ { Beqeq } (*igual igual nos ifs == *)
| EQ { Beq } (*definir igual = *)
| NEQ { Bneq } (*diferente de ~= *)
| POW { Bpow } (*elevado ^*)
| MOD { Bmod }
;
%inline uop:
| FACT { Ufact } (*Fatorial !*)
| DEC { UDec } (*Dec -- *)
| INC { UInc } (*Inc ++ *)
;