【问题标题】:language lexer in OCamlOCaml 中的语言词法分析器
【发布时间】:2017-05-07 23:29:55
【问题描述】:

我正在尝试在 Ocaml 中实现词法分析器。我首先需要做的一部分是获取一个字符串并将它们拆分为字符串列表,以便稍后我可以“标记”它们并将其放入解析器中。它需要通过忽略空格、制表符、换行符等来遵循基本的操作指南。例如:

"1 + 25 *(6^2)"

应该返回

["1"; "+"; "25"; "*"; "("; "6"; "^"; "2"; ")"]

如果一个字符串的开头可以是多个东西,则应该首选最长的匹配,例如:

"1-1" should be split as ["1"; "-1"] since "-1" is a longer match than just "-"

我正在尝试使用Str.regex 来完成这第一步,但它的功能不足以完美拆分它。我的代码:

Str.split (Str.regexp "[ \t\n]+") input

获取input 并根据[ \t\n]+ 拆分它们,所以这里的问题是,如果我有类似(5 + 6^8) 的东西,它将返回["(5"; "+"; "6^8)"] 而不是["("; "5"; "+"; "6"; "^"; "8"; ")"]

知道如何才能做得更好吗?

【问题讨论】:

    标签: split ocaml lexer


    【解决方案1】:

    这就是ocamllex 的用途。您将需要更明确的词汇结构列表,而不是仅仅在空格上进行拆分。

    作为旁注,请务必阅读描述支持哪些正则表达式构造的部分。一个常见的问题是尝试使用来自其他语言的不受支持的结构。

    不管怎样,在词汇级别处理负数是很棘手的,因为您通常想要支持诸如“x-1”之类的东西。如果您尝试按词法处理负数,则会出现两个标记。

    更新

    如果你不能使用 ocamllex,你仍然需要考虑一组正则表达式。

    如果您可以使用 Str 模块,则可以使用 Str.regexp 创建与 ocamllex 相同的正则表达式集。要获取下一个标记,请匹配所有正则表达式并取最长的匹配项。 (要打破长度的关系,请对正则表达式进行排序并取最长长度的第一个匹配项。)

    【讨论】:

    • 我不能使用ocamllex b/c 这是手动实现词法分析器、解析器和解释器的项目的一部分。
    • 如果您被允许使用Str.string_match,您可以匹配您使用 ocamllex 指定的同一组正则表达式,然后取最长的。
    猜你喜欢
    • 2013-01-31
    • 2013-04-29
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多