首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OCamlLex病例-不知觉

OCamlLex病例-不知觉
EN

Stack Overflow用户
提问于 2016-01-28 17:50:38
回答 2查看 377关注 0票数 5

在Ocamllex规范中是否有区分大小写的令牌?我已经尝试以这种方式使区分大小写的令牌:

代码语言:javascript
复制
let token = parser
    ...
   | ['C''c']['A''a']['S''s']['E''e'] { CASE }
    ...

但我在寻找其他的东西,如果存在的话。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-29 04:38:35

使用接受小写和大写的普通标记词法,并在表中查找关键字,忽略大小写:

代码语言:javascript
复制
{
type token = Case | Test | Ident of string

let keyword_tbl = Hashtbl.create 64

let _ = List.iter (fun (name, keyword) ->
    Hashtbl.add keyword_tbl name keyword) [
    "case", Case;
    "test", Test;
  ]
}

let ident_char = ['a'-'z' 'A'-'Z' '_']

rule next_token = parse
  | ident_char+ as s {
      let canon = String.lowercase s in
      try Hashtbl.find keyword_tbl canon
      with Not_found ->
        (* `Ident canon` if you want case-insensitive vars as well
         * as keywords *)
        Ident s
    }
票数 6
EN

Stack Overflow用户

发布于 2016-01-29 16:08:51

正如@gsg所建议的,解决这一问题的正确方法是使用接受小写和大写的普通令牌lexer,然后在表中查找关键字。拥有每个关键字的regexp实际上是ocamllex文档中提到的反模式。

12.7常见错误 ocamllex :转换表溢出,自动机太大由ocamllex生成的确定性自动机最多限于32767次转换。上面的消息表明,您的lexer定义太复杂,超出了这一限制。这通常是由该语言的每个字母关键字都有不同规则的词汇定义造成的,如下例所示。

文档继续使用显式代码示例和使用查找表进行重写。

查找表应该封装查找的“不区分大小写”,因此我们应该使用函数关联结构(read: Map或HashTbl)来定义自己的比较函数。因为我们的查找表可能是不可变的,所以我们选择Map

代码语言:javascript
复制
{
type token = Case | Test | Ident of string

module KeywordTable =
  Map.Make(struct
    type t = string
    let compare a b =
      String.(compare (lowercase a) (lowercase b))
  end)

let keyword_table =
  List.fold_left
    (fun (k, v) -> KeywordTable.add k v))
    [
      "case", Case;
      "test", Test;
    ]
    KeywordTable.empty
}

let ident_char = ['a'-'z' 'A'-'Z' '_']

rule next_token = parse
  | ident_char+ as s {
      try KeywordTable.find keyword_table s
      with Not_found -> Ident s
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35068495

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档