我已经定义了一个哈希表keyword_table
来存储我的语言的所有关键字。以下是部分代码:
(* 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"
returns token CALL
(用于lexer.mll
)和find_1 table CALL
returns "Call"
(用于parser.mly
)。
另外,如果table
可以定义,我应该把它放在哪里以便parser.mly
可以使用它?