我已經定義了一個散列表keyword_table
來存儲我的語言的所有關鍵字。這裏是代碼的一部分:解析中的2個方向(字符串<->標記)表
(* parser.mly *)
%token CALL CASE CLOSE CONST
...
reserved_identifier:
| CALL { "Call" }
| CASE { "Case" }
| CLOSE { "Close" }
| CONST { "Const" }
...
(* lexer.mll *)
{let hash_table list =
let tbl = Hashtbl.create (List.length list) in
List.iter (fun (s, t) -> Hashtbl.add tbl (lowercase s) t) list;
tbl
let keyword_table = hash_table [
"Call", CALL; "Case", CASE; "Close", CLOSE; "Const", CONST;
... ]}
rule token = parse
| lex_identifier as li
{ try Hashtbl.find keyword_table (lowercase li)
with Not_found -> IDENTIFIER li }
由於有很多的關鍵字,我真的很想避免重複的代碼。
在parser.mly
,似乎%token CALL CASE ...
不能簡化,因爲每個標記必須明確定義。但是,對於reserved_identifier
部分,是否可以調用函數來從令牌返回字符串,而不是對每個字符串進行硬編碼?
所以,這表明哈希表可能不適合這個目的。哪種數據結構是雙方搜索的最佳選擇(我們假設雙方的每個密鑰都是唯一的)?因此,我們想要實現find_0 table "Call"
返回令牌CALL
(用於lexer.mll
)和find_1 table CALL
返回"Call"
(用於parser.mly
)。
另外,如果這個table
可以定義,我應該把它放在哪裏,以便parser.mly
可以使用它?