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