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 (将#修改为@)