如何构建正则表达式的最优AST?

时间:2016-06-17 09:38:56

标签: java regex parsing abstract-syntax-tree

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

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

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

1 个答案:

答案 0 :(得分:1)

AST表示特定程序的语法(在OP的情况下,“正则表达式”)被解析。通常,AST派生自实际的解析树,它记录输入程序的特定分解。

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

通常,可能存在不同的输入字符串,具有明显不同的分析树,并且如果分解被标准化则具有相同的AST。这并不总是那么容易。人们可能会发现简单的案例(OP的例子就是其中之一),其中可以为部分语言定义规范形式,并将等效构造强制为规范形式。一般来说,并不总能保证您可以从任意等效的规范生成规范。

或者你可能有,因为OP建议试图选择一个quandry:将[^ x]表示为127个ASCII替代的显式集合是否更好?您应该为[^< 63characters>]选择什么? [^< 64characters>]? [^< 65characters]?那么在Unicode中的[^ x]表示怎么样,可以说有2 ^ 24个字符?

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