如何解决BNF规则到正则表达式
我正在寻找一种方法,以确定BNF语法中的特定规则是否可以转换为正则表达式。
(对于“正则表达式”(RE),我的意思是simple mathematical kind。我对只能通过使用反向引用,环顾四周或其他高级功能才能完成的BNF规则不感兴趣。)
我只对可能的情况感兴趣。
我知道这个问题是generally undecidable,所以我基本上是在寻找技巧来解决这个问题。半确定的东西会很好。
我当前的方法基于这样的思想,即所有非递归规则(不引用自己的规则,不包含引用自己的规则)都可以轻松转换为RE。因此,“我所要做的”就是重写递归规则。简单的例子:
S = a | b S
= b* a
T = a | T b T | T c T
= a | T (b|c) T
= a ( (b|c) a )*
但是,这种方法受到我识别BNF AST中的模式并简单地说AST的能力的限制。这是一种非常有限的方法,所以我正在寻找更好的方法。
以下是解决方案必须能够处理的示例:
S = a | c | S (b S)* c | S d S | S e S ( e S )*
以上规则的语言是常规的。但是,显示出来并不容易,而且需要时间。
证明草图:
S = a | c | S (b S)* c | S d S | S e S ( e S )*
= a | c | S (b S)* c | S d S | S e S
= a | c | S (b S)* c | S (d|e) S
= a | c | S c | S b S (b S)* c | S (d|e) S
现在,让我们忽略S b S (b S)* c
的替代方案:
S' = a|c | S' c | S' (d|e) S'
= (a|c)c* ( (d|e) (a|c)c* )*
返回到S b S (b S)* c
的替代方法:它基本上说,如果输入包含b
,则在b
之后的某个地方,必须有(a|c)c
。这在RE中很难表达,但很容易与NFA一起使用。
构造2个NFA x和y,使得x = S'
和y = S' (b S')* c
。每当我们处于x的最终状态时,就通过b
过渡到y的初始状态。每当我们处于y的最终状态时,都要通过epsilon转换到x的所有最终状态。最终NFA将具有x的初始状态和最终状态。最终NFA的RE为:(a|c) ( c | (d|e)(a|c) | b(a|c) ( (b|d|e)(a|c) )* c )*
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。