目标:找到一种正式定义语法的方法,该语法以任意顺序识别0或1次集合中的元素。随后,我想解析它并生成一个AST。
例如:假设我的语言中的有效字符串集合为{A, B, C}
。我想定义一个语法,该语法识别任何数量的这些元素的所有有效排列。
语法上有效的字符串包括:
A
,B A
和C A B
语法无效的字符串包括:
A A
和B A C B
要明确的是,在CFG中明确定义所有可能的排列对我来说是不可接受的,因为无法维护较大的集合。
根据我的理解,这样的语言失败the pumping lemma for context free languages,因此解决方案不会没有上下文或定期。
我所追求的被称为“排列语言”,Benedek Nagy已经做了一些理论工作,作为上下文无关语言的扩展。
关于解析器生成器,我只发现了实现具有置换阶段(link)的解析器的讨论。解析器显然在生成的CFG的大小上具有指数下限,并且我无论如何都找不到支持它的任何解析器生成器。
这个问题的一种解决方案是written in ANTLR。它使用语义谓词来“编码”问题。
答案 0 :(得分:1)
假设替换字符串集是固定的并且事先已知,比如大小 n ,可以提出一个大小为 O(n)的(非上下文无关)语法!)。这并非渐近地小于枚举所有排列,因此我认为它不能被认为是一个好的解决方案。我相信这个语法可以重新表述为上下文敏感语法(虽然我在下面建议的形式不是这样)。
对于问题中提到的示例{a, b, c}
,一个这样的语法如下。按惯例,我使用小写字母表示终端符号,使用大写字母表示非终端。 S
是最初的非终端符号。
S ::= XabcY
XabcY ::= aXbcY | bXacY | cXabY
XabY ::= ab | ba
XacY ::= ac | ca
XbcY ::= bc | cb
非终端X
和Y
将生成中尚未最终确定的子字符串括起来;这个子字符串最终将被X
和Y
之间给出的终端的排列(以某种任意顺序)替换。