63 lines
1.4 KiB
OCaml
63 lines
1.4 KiB
OCaml
/* File parser.mly */
|
|
%token <string> INT
|
|
%token <string> ID
|
|
%token PLUS MINUS TIMES DIV
|
|
%token LPAREN RPAREN ASSIGN IN IMPLY FUNC
|
|
%token EOL
|
|
%right IMPLY FUNC
|
|
%left PLUS MINUS/* lowest precedence */
|
|
%left TIMES DIV /* medium precedence */
|
|
%nonassoc UMINUS/* highest precedence */
|
|
%start main /* the entry point */
|
|
%type <Ast.ast> main
|
|
%%
|
|
main:
|
|
blocks EOL{ $1 }
|
|
;
|
|
blocks:
|
|
block{ $1 }
|
|
|blocks block{match $1 with Ast.Node x -> Ast.Node (x @ [$2])
|
|
| Ast.Int x -> Ast.Node[$1; $2] | Ast.Leaf x -> Ast.Node [$1; $2]} /* It Must not be entered */
|
|
;
|
|
|
|
block:
|
|
expr {$1}
|
|
| let_bind {$1}
|
|
;
|
|
|
|
let_bind:
|
|
| typ ID ASSIGN expr IN block {Ast.Node [Ast.Leaf "%let"; Ast.Node[$1; Ast.Leaf $2; $4]; $6]}
|
|
;
|
|
|
|
typ:
|
|
| ID {Ast.Leaf $1}
|
|
| typ IMPLY typ {Ast.Node [Ast.Leaf "->"; $1 ; $3]}
|
|
|
|
expr:
|
|
app_expr {$1}
|
|
| bin_expr {$1}
|
|
| lam_expr{$1}
|
|
;
|
|
|
|
lam_expr:
|
|
arg FUNC block {Ast.Node [Ast.Leaf "%lambda"; $1 ; $3]}
|
|
;
|
|
arg:
|
|
typ ID { Ast.Node [$1;Ast.Leaf $2] }
|
|
;
|
|
|
|
app_expr:
|
|
expr expr { Ast.Node [ Ast.Leaf "%apply"; $1; $2] }
|
|
;
|
|
;
|
|
bin_expr:
|
|
INT { Ast.Int (int_of_string $1)}
|
|
| ID { Ast.Leaf $1 }
|
|
| LPAREN expr RPAREN { $2 }
|
|
| expr PLUS expr { Ast.Node [ Ast.Leaf "+"; $1; $3] }
|
|
| expr MINUS expr { Ast.Node[ Ast.Leaf "-"; $1 ; $3] }
|
|
| expr TIMES expr { Ast.Node[ Ast.Leaf "*"; $1 ;$3] }
|
|
| expr DIV expr { Ast.Node[ Ast.Leaf "/"; $1; $3] }
|
|
| MINUS expr %prec UMINUS { Ast.Node[ Ast.Leaf "-" ; $2] }
|
|
;
|
|
|