/* File parser.mly */ %token INT %token 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 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] } ;