Files
lci/lib/miniFun/Parser.mly
2025-01-15 00:10:44 +01:00

98 lines
3.3 KiB
OCaml

(* code to be copied in the scanner module *)
(*
*)
%{
open Types
%}
(* tokens *)
%token TYPEBOOL TYPEINT TYPEFUNCTION
%token LAMBDA RAND IF IN THEN ELSE LET REC BNOT POWERMOD RESULTS
%token <bool> BOOL
%token <string> VARIABLE
%token <int> INT
%token COMMA COLUMN LEFTPAR RIGHTPAR CMPLESS CMPGREATER PLUS MINUS TIMES
%token DIVISION MODULO POWER ASSIGNMENT BAND BOR CMP CMPLESSEQ CMPGREATEREQ
%token FIRST SECOND
%token EOF
%type <t_exp> prg
%type <t_exp> texp
%type <ftype> typeexp
(* start nonterminal *)
%start prg
(* associativity in order of precedence *)
%left lowest
%right TYPEFUNCTION
%left COMMA
%nonassoc INT BOOL VARIABLE
%left POWERMOD
%left IF
%left BOR BAND
%left CMP CMPLESS CMPLESSEQ CMPGREATER CMPGREATEREQ
%left PLUS MINUS
%left TIMES DIVISION MODULO
%right POWER
%right BNOT RAND
%left FIRST SECOND
%left LAMBDA
%left LET
%left LEFTPAR
%right righthighest
%%
(* grammar *)
prg:
| e = texp; EOF {e}
texp:
| i = INT {Integer (i)}
| b = BOOL {Boolean (b)}
| a = VARIABLE {Variable (a)}
| LEFTPAR; a = texp; COMMA; b = texp; RIGHTPAR
{Tuple (a, b)}
| LAMBDA; v = VARIABLE; COLUMN; t = typeexp; RESULTS; body = texp
%prec lowest {Function (v, t, body)}
| a = texp; b = texp {Application (a, b)} %prec righthighest
| a = texp; PLUS; b = texp {Plus (a, b)}
| a = texp; MINUS; b = texp {Minus (a, b)}
| a = texp; TIMES; b = texp {Times (a, b)}
| a = texp; DIVISION; b = texp {Division (a, b)}
| a = texp; MODULO; b = texp {Modulo (a, b)}
| a = texp; POWER; b = texp {Power (a, b)}
| a = texp; BAND; b = texp {BAnd (a, b)}
| a = texp; BOR; b = texp {BOr (a, b)}
| FIRST; a = texp {First (a)}
| SECOND; a = texp {Second (a)}
| a = texp; CMP; b = texp {Cmp (a, b)}
| a = texp; CMPLESS; b = texp {CmpLess (a, b)}
| a = texp; CMPLESSEQ; b = texp {CmpLessEq (a, b)}
| a = texp; CMPGREATER; b = texp {CmpGreater (a, b)}
| a = texp; CMPGREATEREQ; b = texp {CmpGreaterEq (a, b)}
| POWERMOD; LEFTPAR; t1 = texp; COMMA;
t2 = texp; COMMA;
t3 = texp; RIGHTPAR
{PowerMod (t1, t2, t3)}
| RAND; t = texp; {Rand (t)}
| BNOT; b = texp {BNot (b)}
| IF; b = texp; THEN; c1 = texp; ELSE; c2 = texp;
%prec lowest {IfThenElse (b, c1, c2)}
| LET; v = VARIABLE; ASSIGNMENT; c = texp; IN; rest = texp
%prec lowest {LetIn (v, c, rest)}
| LET; REC; f = VARIABLE; x = VARIABLE; COLUMN; t = typeexp; ASSIGNMENT; body = texp; IN; rest = texp
%prec lowest {LetFun (f, x, t, body, rest)}
| LEFTPAR; a = texp; RIGHTPAR {a}
typeexp:
| TYPEINT {IntegerType}
| TYPEBOOL {BooleanType}
| v = delimited(LEFTPAR, typeexp, RIGHTPAR)
{v}
| a = typeexp; COMMA; b = typeexp {TupleType (a, b)}
| vin = typeexp; TYPEFUNCTION; vout = typeexp
{FunctionType (vin, vout)}