-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParser.fsy
68 lines (58 loc) · 1.8 KB
/
Parser.fsy
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
%{
// AST
type Expr =
| Func of string * string list * Expr
| Extern of string * string list
| Call of Expr * Expr list
| Number of float
| Variable of string
| Binop of (string * int) * Expr * Expr
let balance_binop(op, lhs, rhs) =
let ops, prec = op
match lhs, rhs with
| Binop ((lops, lprec) as lop, ll, lr), rhs when lprec < prec ->
Binop (lop, ll, Binop(op, lr, rhs))
| lhs, Binop ((rops, rprec) as rop, rl, rr) when rprec < prec ->
Binop (rop, Binop(op, lhs, rl), rr)
| _ -> Binop(op, lhs, rhs)
// Error Handling
open FSharp.Text.Parsing
type ParseError (token, shift_tokens, reduce_tokens) =
inherit exn()
member __.Data = (token, shift_tokens, reduce_tokens)
let f_parse_error_rich<'t> (ctx:ParseErrorContext<'t>) =
ignore (raise (ParseError(sprintf "%O" ctx.CurrentToken, ctx.ShiftTokens, ctx.ReduceTokens)))
let parse_error_rich = Some f_parse_error_rich
%}
%token DEF EXTERN
%token <string> IDENTIFIER
%token <float> NUMBER
%token <string * int> BINOP
%token SEMI COMMA LPAREN RPAREN EOF
%start start
%type <Expr list> start
%%
start : lines SEMI { $1 }
lines : line { [$1] } | lines line { $1 @ [$2] }
line:
| DEF prototype expr { Func (fst $2, snd $2, $3) }
| EXTERN prototype { Extern (fst $2, snd $2) }
| expr { $1 }
expr:
| primary { $1 }
| IDENTIFIER LPAREN comma_exprs RPAREN { Call(Variable $1, $3) }
| expr BINOP expr { balance_binop($2, $1, $3) }
primary :
| NUMBER { Number $1 }
| IDENTIFIER { Variable $1 }
| LPAREN expr RPAREN { $2 }
comma_exprs: { [] } | comma_exprs_1 { $1 }
comma_exprs_1:
| expr { [$1] }
| comma_exprs_1 COMMA expr { $1 @ [$3] }
arguments:
| IDENTIFIER { [$1] }
| arguments IDENTIFIER { $1 @ [$2] }
prototype:
| IDENTIFIER LPAREN arguments RPAREN { $1, $3 }
| IDENTIFIER LPAREN RPAREN { $1, [] }