summaryrefslogtreecommitdiff
path: root/minijazz/src/parser/parser.mly
diff options
context:
space:
mode:
Diffstat (limited to 'minijazz/src/parser/parser.mly')
-rw-r--r--minijazz/src/parser/parser.mly185
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 }
+%%