【发布时间】:2013-10-23 21:10:18
【问题描述】:
我已经定义了一个哈希表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"返回令牌CALL(用于lexer.mll)和find_1 table CALL返回"Call"(用于parser.mly)。
另外,如果这个table可以定义,我应该把它放在哪里让parser.mly可以使用它?
【问题讨论】:
标签: parsing ocaml lexer ocamlyacc ocamllex