uann/ocaml_yacc/parser.mly

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] }
;