【问题标题】:How to build an optimal AST of a regular expression?如何构建正则表达式的最佳 AST?
【发布时间】:2016-06-17 09:38:55
【问题描述】:

我正在尝试通过从头开始构建抽象语法树来构建正则表达式解析器(没有任何项目依赖项或工具,例如 Java 中的杯子解析器等)。我不想保存正则表达式中包含的所有信息,而是想尽可能地简化它。

例如,x::=y|z 应该导致与字符类x::=[yz] 相同的 AST。但是,由于正则表达式可以(并且确实)变得非常复杂,我无法决定要实现哪些等价。比如我不知道如何保存否定选择x::=[^b],相当于x::=a|c|d|e|...

你会做什么抽象?这些抽象中的一些会在以后导致错误的 AST 吗?

【问题讨论】:

  • 您应该将字符类分开。考虑一下:Unicode 定义了超过 120k 个字符,因此[^b] 将代表大约 120k 个成员的交替。这对 AST 没有任何好处。

标签: java regex parsing abstract-syntax-tree


【解决方案1】:

一个 AST 代表被解析的特定程序的语法(在 OP 的情况下,一个“正则表达式”)。通常 AST 来源于一棵实际的分析树,它记录了输入程序的特定分解。

OP 建议他想要一个 AST,该 AST 表示与字符类相同的字符交替。他似乎将“等效”或“规范”形式与特定解析混淆了。

一般来说,如果分解被归一化,可能会有不同的输入字符串,具有明显不同的解析树,以及相同的 AST。这并不总是容易做到的。人们可能会发现简单的案例(OP 的示例就是其中之一),其中可以为语言的一部分定义规范形式并将等效结构强制转换为该规范形式。一般来说,并不总是能保证您可以从任意等效的生成规范。

或者您可能有,正如 OP 建议的那样,试图选择一个:将 [^x] 表示为 127 个 ASCII 替代项的显式集合是否更好?您应该为 [^] 选择什么? [^]? [^

实际上,我建议 OP 生成解析树和/或与该解析树对应的任何 AST。然后,他可以尝试将 AST 标准化为规范形式,如果这样做有意义的话,但这最好作为一个单独的步骤。

【讨论】:

    猜你喜欢
    • 2010-12-06
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2011-12-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    相关资源
    最近更新 更多