【发布时间】:2021-12-02 17:38:26
【问题描述】:
背景:我正在尝试解决这个 leetcode 问题:regular-expression-matching。我的方法是实现一个 LL(1) 解析器生成器,对于这个问题可能有点矫枉过正,但这只是脑力锻炼。
我只有解析器理论的入门级知识,如果我问的是一个愚蠢的问题,请原谅。
所以,这个测试用例我失败了。要求是正则表达式模式应该匹配整个字符串
Regex: a*a
Input: aaa
我不知道如何将此模式转换为 LL(1) 解析器。
在我看来,a*a 模式可以转换为生产规则:
S -> Aa # a*a
A -> aA | ε # a*
解析表:
| a | $ | |
|---|---|---|
| S | S -> Aa | |
| A | A -> aA | A -> ε |
解析步骤如下:
0: S$ aaa$ # use [S,a]
1: Aa$ aaa$ # use [A,a]
2: aAa$ aaa$ # eat 'a'
3: Aa$ aa$ # use [A,a]
4: aAa$ aa$ # eat 'a'
5: Aa$ a$ # use [A,a]
6: aAa$ a$ # eat 'a'
7: Aa$ $ # use [A,$]
8: a$ $ # Error!
正确的匹配应该是:
a* -> aa
a -> a
但我得到的是:
a* -> aaa
a -> Error!
我不知道我错过了哪一部分????。
【问题讨论】:
-
您不能为此构造 LL(1) 解析器。您可以使用递归下降解析器或 LL(2) 解析器,因为那是 LL(2) 语法。这是一个或多个
a。a+可以识别相同的语言。 -
左重构可能会对您有所帮助,因为您似乎对从正则表达式生成的语法没有限制。
-
您的 LL(1) 解析器表不正确。尝试使用Grammophone 或Kocman's LL(k) generator 来检查您的解决方案。在转换为语法之前,您肯定希望将诸如“a*a”之类的模式重写为“a+”。