diff options
Diffstat (limited to 'minijazz/src/parser/parser.mly')
-rw-r--r-- | minijazz/src/parser/parser.mly | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/minijazz/src/parser/parser.mly b/minijazz/src/parser/parser.mly new file mode 100644 index 0000000..126ab36 --- /dev/null +++ b/minijazz/src/parser/parser.mly @@ -0,0 +1,185 @@ +%{ + +open Ident +open Static +open Ast +open Location +open Misc + +let fresh_param () = + mk_static_exp (SVar ("_n"^(Misc.gen_symbol ()))) + +%} + +%token INLINED ROM RAM WHERE END CONST PROBING +%token LPAREN RPAREN COLON COMMA EQUAL REG OR XOR NAND AND POWER SLASH +%token EOF RBRACKET LBRACKET GREATER LESS NOT SEMICOL PLUS MINUS STAR +%token IF THEN ELSE LEQ DOT DOTDOT +%token <string> NAME +%token <string> STRING +%token <int> INT +%token <string> BOOL_INT +%token <bool> BOOL + +%left DOT +%left OR PLUS +%left LEQ EQUAL +%right MINUS +%left NAND XOR AND +%left STAR SLASH +%right NOT REG +%right POWER + +%start program +%type <Ast.program> program + +%% + +/** Tools **/ +%inline slist(S, x) : l=separated_list(S, x) {l} +%inline snlist(S, x) : l=separated_nonempty_list(S, x) {l} +%inline tuple(x) : LPAREN h=x COMMA t=snlist(COMMA,x) RPAREN { h::t } +%inline tag_option(P,x): + |/* empty */ { None } + | P v=x { Some(v) } + +localize(x): y=x { y, (Loc($startpos(y),$endpos(y))) } + +program: + | c=const_decs n=node_decs EOF + { mk_program c n } + +const_decs: c=list(const_dec) {c} +const_dec: + | CONST n=name EQUAL se=static_exp option(SEMICOL) + { mk_const_dec ~loc:(Loc($startpos,$endpos)) n se } + +name: n=NAME { n } + +ident: + | n=name { ident_of_string n } + +type_ident: LBRACKET se=static_exp RBRACKET { TBitArray se } + +node_name: + | n=name { reset_symbol_table (); n } + +node_decs: ns=list(node_dec) { ns } +node_dec: + inlined=inlined_status n=node_name p=params LPAREN args=args RPAREN + EQUAL out=node_out WHERE b=block probes=probe_decls END WHERE option(SEMICOL) + { mk_node n (Loc ($startpos,$endpos)) inlined args out p b probes } + +node_out: + | a=arg { [a] } + | LPAREN out=args RPAREN { out } + +inlined_status: + | INLINED { Inlined } + | /*empty*/ { NotInlined } + +params: + | /*empty*/ { [] } + | LESS pl=snlist(COMMA,param) GREATER { pl } + +param: + n=NAME { mk_param n } + +args: vl=slist(COMMA, arg) { vl } + +arg: + | n=ident COLON t=type_ident { mk_var_dec n t } + | n=ident { mk_var_dec n TBit } + +block: + | eqs=equs { BEqs (eqs, []) } + | IF se=static_exp THEN thenb=block ELSE elseb=block END IF { BIf(se, thenb, elseb) } + +equs: eq=equ tl=equ_tail { eq::tl } +equ_tail: + | /*empty*/ { [] } + | SEMICOL { [] } + | SEMICOL eq=equ tl=equ_tail { eq::tl } +equ: p=pat EQUAL e=exp { mk_equation p e } + +pat: + | n=ident { Evarpat n } + | LPAREN p=snlist(COMMA, ident) RPAREN { Etuplepat p } + +static_exp: se=_static_exp { mk_static_exp ~loc:(Loc ($startpos,$endpos)) se } +_static_exp : + | i=INT { SInt i } + | n=NAME { SVar n } + | LPAREN se=_static_exp RPAREN { se } + /*integer ops*/ + | se1=static_exp POWER se2=static_exp { SBinOp(SPower, se1, se2) } + | se1=static_exp PLUS se2=static_exp { SBinOp(SAdd, se1, se2) } + | se1=static_exp MINUS se2=static_exp { SBinOp(SMinus, se1, se2) } + | se1=static_exp STAR se2=static_exp { SBinOp(SMult, se1, se2) } + | se1=static_exp SLASH se2=static_exp { SBinOp(SDiv, se1, se2) } + /*bool ops*/ + | se1=static_exp EQUAL se2=static_exp { SBinOp(SEqual, se1, se2) } + | se1=static_exp LEQ se2=static_exp { SBinOp(SLeq, se1, se2) } + +exps: LPAREN e=slist(COMMA, exp) RPAREN {e} + +exp: e=_exp { mk_exp ~loc:(Loc ($startpos,$endpos)) e } +_exp: + | e=_simple_exp { e } + | c=const { Econst c } + | REG e=exp { Ereg e } + | n=NAME p=call_params a=exps { Ecall (n, p, a) } + | e1=exp PLUS e2=exp { Ecall ("or", [], [e1; e2]) } + | e1=exp OR e2=exp { Ecall ("or", [], [e1; e2]) } + | e1=exp AND e2=exp { Ecall ("and", [], [e1; e2]) } + | e1=exp POWER e2=exp { Ecall("xor", [], [e1; e2]) } + | e1=exp XOR e2=exp { Ecall ("xor", [], [e1; e2]) } + | e1=exp NAND e2=exp { Ecall ("nand", [], [e1; e2]) } + | NOT a=exp { Ecall ("not", [], [a])} + | e1=exp DOT e2=exp + { Ecall("concat", [fresh_param(); fresh_param(); fresh_param ()], [e1; e2]) } + | e1=simple_exp LBRACKET idx=static_exp RBRACKET + { Ecall ("select", [idx; fresh_param()], [e1]) } + | e1=simple_exp LBRACKET low=static_exp DOTDOT high=static_exp RBRACKET + { Ecall("slice", [low; high; fresh_param()], [e1]) } + | e1=simple_exp LBRACKET low=static_exp DOTDOT RBRACKET + { let n = fresh_param () in + let high = mk_static_exp (SBinOp(SMinus, n, mk_static_exp (SInt 1))) in + Ecall("slice", [low; high; n], [e1]) } + | e1=simple_exp LBRACKET DOTDOT high=static_exp RBRACKET + { + let params = [mk_static_exp (SInt 0); high; fresh_param ()] in + Ecall("slice", params, [e1]) + } + | ro=rom_or_ram LESS addr_size=static_exp + COMMA word_size=static_exp input_file=tag_option(COMMA, STRING) GREATER a=exps + { Emem(ro, addr_size, word_size, input_file, a) } + +simple_exp: e=_simple_exp { mk_exp ~loc:(Loc ($startpos,$endpos)) e } +_simple_exp: + | n=ident { Evar n } + | LPAREN e=_exp RPAREN { e } + +const: + | b=BOOL { VBit b } + | b=BOOL_INT { VBitArray (bool_array_of_string b) } + | i=INT + { match i with + | 0 -> VBit false + | 1 -> VBit true + | _ -> raise Parsing.Parse_error + } + | LBRACKET RBRACKET { VBitArray (Array.make 0 false) } + +rom_or_ram : + | ROM { MRom } + | RAM { MRam } + +call_params: + | /*empty*/ { [] } + | LESS pl=snlist(COMMA,static_exp) GREATER { pl } + +probe_decls: + | /*empty*/ { [] } + | PROBING l=separated_nonempty_list(COMMA, ident) { l } +%% |