我有一个表示表达式的语法。让我们说简单就是:
S -> E
E -> T + E | T
T -> P * T | P
P -> a | (E)
a
,+
,*
,(
和)
是我字母表中的字母。
上述规则可以使用正确的操作顺序和相关性生成包含括号,乘法和加法的有效算术表达式。
我的目标是接受包含0或更多字母表字母的每个字符串。以下是我的约束:
EOF
终端有助于检测超出其他有效表达式的额外令牌。)此外,我希望额外的规则对应于不同类型的错误(缺少二进制操作的参数,缺少括号 - 左或右 - 超出其他可接受表达式的额外标记等)。我这样说是因为可能有一些微不足道的方式来回答我的问题,“接受”所有输入,否则这些输入对错误报告没有好处。
我发现这些规则很有用,虽然我不知道它们是否违反我的约束条件:
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]
其中$
是显式EOF
令牌,@
是空字符串。
如果我的问题不明确:如何在我的约束中修改我的语法以实现我接受所有输入的目标,最好是将规则与错误类型很好地对应?我的规则符合我的目标吗?
答案 0 :(得分:2)
这个问题已经存在了一段时间,涵盖了主题中初学者经常访问的主题。人们经常发现那些在本科学位完成编译课程的人都知道这是其中一个没有简单或单一答案的问题。你可能已经注意到你有two questions on the same topic,但都没有得到回答。 Another question someone else posted回答了指向文献的指示,解释了为什么这很难。
这个问题至今仍存在了50多年。如果随着时间的推移检查文献,从早期的会议论文,课程教科书,博士论文和(今天)SO
,我们可以看到经常提到这是错误的问题这一事实! (或者更确切地说是解决问题的方法)。
多年来从课程文本中抽取样本(从我的书架中随机选择):
Gries,D。(1970)错误恢复和更正 - 由Bauer,F.L。编辑的编译器构建,高级课程的文献介绍。 &安培; Eickel,J.,Springer Verlag,pp.627-638
Gries,D。(1971)数字计算机编译器构建,Wiley,pp.320-326。
Aho,A.V.,Ullman,J.D。(1977)编译器设计原理,Addison Wesley,pp.397-405。
Bornat,R。(1979)理解和编写编译器,Macmillan,pp.251-252。
Hanson,D。(1995) A retargetable C 编译器:设计与实现,Addison-Wesley,pp.140-146。
Grune,D.,Bal,H.E.,Jacobs,C.J.H。 &安培; Langendoen,K.G。 (2000)现代编译器设计,Wiley,pp.175-184
Aho,A.V.,Lam,M.S.,Sethi,R.,Ullman,J.D。(2007) Compilers:Principles,Techniques,& Sons,Inc。工具,Pearson,Addison-Wesley,pp.283-296。
所有这些(超过40年)都同意你的问题是错误地使用错误的工具或走错方向。我想我想说“你不能从这里来”。你应该从其他地方开始。
如果你想要更深层次的东西,那就有一篇完整的博士论文:
希望对于那些将来再次访问此问题的人来说,有一个占位符可供答案。
<小时/> 我从您对其他问题的评论中注意到您使用的是MPPG,源自CPPG。不是每个人都会使用这些,所以我要包含一些指向这些工具的链接:
Managed Babel Systems Essentials
Garden Points Parser Generator
Irony .NET compiler Construction Kit
Writing your first Visual Studio Language Service