【问题标题】:How to construct a CFG based on a given regular expression如何根据给定的正则表达式构造 CFG
【发布时间】:2014-05-03 19:13:12
【问题描述】:

我试图弄清楚如何根据给定的正则表达式构造一个 CFG(上下文无关语法)。 例如,a(ab)*(a|b) 我认为有一个算法可以通过,但它真的很混乱。 这是我到目前为止得到的:

    S->aAB; 
    A->aAb|empty;
    B->a|b;

这看起来对吗? 任何帮助将不胜感激。

【问题讨论】:

  • 嗨,欢迎来到 StackOverflow。这里的问题通常会包含一些关于您迄今为止尝试过的内容以及您面临的特定问题的信息。这个问题更广泛地要求一个通用算法,可能可以在网上其他地方找到。
  • 请点击问题下方的编辑;不要试图在注释中包含代码。
  • 对不起,这是我的第一篇文章,仍在尝试弄清楚这个论坛是如何运作的。

标签: regex algorithm context-free-grammar


【解决方案1】:

将 CFG 分为三部分,分别用于 a(ab)*(a|b)

对于(a|b),你有B -> a | b 正确。

(ab)* 表示类似abababababab 等字符串。所以A -> abA | empty 将是正确的生产方式。

因此,完整的语法变为:

S -> aAB
A -> abA | empty
B -> a | b

注意:A -> aAb | empty 会派生出abaabbaaabbb 等字符串,这不是regular language,也不可能代表regular expression

【讨论】:

【解决方案2】:

为给定的正则表达式构造上下文无关文法的另一种方法是:

  1. 构造一个接受与正则表达式相同的语言的有限状态机。
  2. 创建一个语法,其终结符是正则表达式字母表中的终结符,其非终结符是(或对应 1:1 到)状态机中的状态,并且具有 X -> t Y 形式的规则每个状态机在终端符号 t 上从状态 X 转换到状态 Y。如果您的 CFG 表示法允许,则每个最终状态 F 都会获得 F -> epsilon 形式的规则。如果您的 CFG 表示法不允许这样的规则,那么对于终端 t 上从状态 X 到最终状态 F 的每次转换,生成规则 X -> t(除了已经描述的规则 X -> t F)。结果是一个正则文法,一种上下文无关文法,它遵守每个右侧最多有一个非终结符的附加约束。

对于给出的示例,假设我们构造了以下 FSA(其中许多接受与正则表达式相同的语言):

由此可以直接推导出以下正则文法:

S -> a A1
A1 -> a A2
A2 -> b B3
B3 -> a A2
B3 -> a A4
B3 -> b B5
A1 -> a A4
A1 -> b B5
A4 -> epsilon
B5 -> epsilon
epsilon -> 

或者,如果我们不想要右侧为空的规则,则删除该语法的最后三个规则并添加:

A1 -> a
A1 -> b
B3 -> a
B3 -> b

与其他方法相比,这种方法的缺点是生成的语法比它需要的更冗长,而其优点是推导可以完全机械化,这意味着无需费力思考就更容易正确。

【讨论】:

  • 应该是`A1 -> b B5`。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
  • 2021-12-02
  • 1970-01-01
相关资源
最近更新 更多