我想知道如何在使用ocamlyacc和ocamllex編寫文法時處理語句中的變量引用。如何處理yacc/bison中的變量引用(使用ocaml)
的問題是,形式
var x = y + z
var b = true | f;
的語句應該既是正確的,但在第一種情況下變量是指數,而在第二種情況下是f
一個布爾變量。
在我寫我有這個語法:
numeric_exp_val:
| nint { Syntax.Int $1 }
| FLOAT { Syntax.Float $1 }
| LPAREN; ne = numeric_exp; RPAREN { ne }
| INCR; r = numeric_var_ref { Syntax.VarIncr (r,1) }
| DECR; r = numeric_var_ref { Syntax.VarIncr (r,-1) }
| var_ref { $1 }
;
boolean_exp_val:
| BOOL { Syntax.Bool $1 }
| LPAREN; be = boolean_exp; RPAREN { be }
| var_ref { $1 }
;
這顯然不能工作,因爲這兩個var_ref
非終端降低到相同的(減少/減少衝突)。但是我希望在解析階段本身進行大部分靜態完成的類型檢查(對於變量引用)。
這就是爲什麼我想知道哪些是具有變量引用和保持此結構的最佳方式。只是作爲一個附加的信息,我有,通過將其轉化爲類似於這一個字節碼編譯語法樹功能:
let rec compile_numeric_exp exp =
match exp with
Int i -> [Push (Types.I.Int i)]
| Float f -> [Push (Types.I.Float f)]
| Bop (BNSum,e1,e2) -> (compile_numeric_exp e1) @ (compile_numeric_exp e2) @ [Types.I.Plus]
| Bop (BNSub,e1,e2) -> (compile_numeric_exp e1) @ (compile_numeric_exp e2) @ [Types.I.Minus]
| Bop (BNMul,e1,e2) -> (compile_numeric_exp e1) @ (compile_numeric_exp e2) @ [Types.I.Times]
| Bop (BNDiv,e1,e2) -> (compile_numeric_exp e1) @ (compile_numeric_exp e2) @ [Types.I.Div]
| Bop (BNOr,e1,e2) -> (compile_numeric_exp e1) @ (compile_numeric_exp e2) @ [Types.I.Or]
| VarRef n -> [Types.I.MemoryGet (Memory.index_for_name n)]
| VarIncr ((VarRef n) as vr,i) -> (compile_numeric_exp vr) @ [Push (Types.I.Int i);Types.I.Plus;Types.I.Dupe] @ (compile_assignment_to n)
| _ -> []
我只是分體式檢查從分析階段。我知道,我只是懶惰但利用類型推斷+解析強大功能來自動檢查的可能性真的很誘人:) – Jack