2

我有一个表示表达式的语法。为简单起见,假设它是:

S -> E
E -> T + E | T
T -> P * T | P
P -> a | (E)

, a, +,*和是我的字母表中的字母()

上述规则可以使用正确的运算顺序和关联性生成包含括号、乘法和加法的有效算术表达式。

我的目标是接受每个字符串,其中包含 0 个或更多字母。这是我的限制:

  • 语法必须“接受”所有包含 0 个或多个字母的字符串。
  • 可以通过算法引入新终端并将其插入到输入中。(我发现EOF,出于某种原因,在检测到超出其他有效表达式的额外标记时,显式提供终端会有所帮助。)
  • 可能会引入新的生产规则。新规则将是错误标志(即,如果使用 1 解析字符串,那么尽管字符串被接受,但在语义上被认为是错误)。
  • 可以修改产生规则以便插入新引入的终端。
  • 语法应该是 LALR(1),至少可以由 Lex/Yacc 类工具处理(如果我记得悬空的 else 问题需要非 LALR(1),尽管与 Lex/Yacc 兼容)。

此外,我希望额外的规则对应于不同类型的错误(缺少二进制操作的参数、缺少括号 - 左或右 - 超出其他可接受的表达式的额外标记等)。我这么说是因为可能有一些简单的方法可以回答我的问题以“接受”所有输入,否则这些输入对错误报告无益。

我发现这些规则很有用,尽管我不知道它们是否违反了我的约束:

P -> @      [error]
P -> (E     [error]
S -> E $    [instead of S -> E]
S -> E X $  [error]
X -> X Y    [error]
X -> Y      [error]
Y -> a      [error]
Y -> (      [error]
Y -> )      [error]
Y -> *      [error]
Y -> +      [error]

where$是显式EOF标记,@是空字符串。


如果我的问题不清楚:如何在我的约束范围内修改我的语法以实现接受所有输入的目标,最好是规则与错误类型的良好对应?我的规则是否符合我的目标?

4

1 回答 1

2

这个问题已经存在了一段时间,涵盖了该主题的初学者经常访问的主题。人们经常会发现,那些在本科阶段上过编译器课程的人都知道,这是那些没有简单或单一答案的问题之一。您可能已经注意到您有两个关于同一主题的问题,但都没有得到回答。其他人发布的另一个问题是通过指向解释为什么这很难的文献来回答的。

这是一个存在 50 多年的问题。如果随着时间的推移检查文献,从早期的会议论文、课程教科书、博士论文和(今天)SO,我们可以看到经常提到这是一个错误的问题这一事实!(或者更确切地说是解决问题的错误方法)。

只是从多年来的课程文本中抽取样本(从我的书架上随机选择):

Gries, D. (1970) 错误恢复和纠正 - 文献简介,编译器构造,高级课程,由 Bauer, FL & Eickel, J., Springer Verlag, pp.627-638 编辑。
Gries, D. (1971)数字计算机的编译器构建,Wiley,pp.320-326。
Aho, AV, Ullman, JD (1977)编译器设计原理,Addison Wesley,pp.397-405。
Bornat, R. (1979)理解和编写编译器,Macmillan,pp.251-252。
Hanson, D. (1995) A retargetable C compiler: Design and Implementation , Addison-Wesley, pp.140-146。
Grune, D., Bal, HE, Jacobs, CJH & Langendoen, KG (2000)现代编译器设计,Wiley,第 175-184 页。
Aho, AV, Lam, MS, Sethi, R., Ullman, JD (2007)编译器:原理、技术和工具,Pearson, Addison-Wesley,pp.283-296。

所有这些(超过 40 年的跨度)都同意您的问题是关于错误地使用错误的工具或朝着错误的方向前进。我想我想说“你不能从这里到那里”。你应该从别的地方开始。

如果你想要更深层次的东西,有一个完整的博士论文:

Charles, P. (1991) A Practical method for Constructing Efficient LALR(k) Parser with Automatic Error Recovery,纽约大学

希望将来再次访问此问题的人可以找到答案的占位符。


我从对您的其他问题的评论中注意到您正在使用源自 CPPG 的 MPPG。不是每个人都会使用这些工具,所以我提供了一些指向这些工具的链接:

Managed Babel Systems Essentials
Garden Points Parser Generator
Irony .NET 编译器构建工具包
编写您的第一个 Visual Studio 语言服务

于 2015-04-21T16:06:09.513 回答