我正在使用一些解析器和词法分析器生成工具(类似于Lex和Bison,但是对于C#)来生成程序,这些程序将字符串解析为抽象语法树,以后可以进行评估。
我想进行错误恢复(即在生成的抽象句子树中报告缺少令牌等)。我有两种方法来构建生成的语法,我想知道哪种方法更好/更灵活/不会有冲突(.y和.lex文件是根据描述生成的计算器)。
计算器描述允许用户指定终端/正则表达式及其对操作符的位置和关联性。如下所示:
grammar.AddTerminal("Plus", "\\+").
AddNonTerminal(new NonTerminal("Add", Associativity.LeftToRight).
AddTerminal("Expression").
AddTerminal("Plus").
AddTerminal("Expression"));
(优先级是通过添加Terminal
和NonTerminal
的顺序指定的。"Add"
是通过Reflection发现的方法的名称。基本上它告诉NonTerminal在抽象语法树中调用运算符的内容。)
方法1 :(允许任何表达式的空规则)
S -> E
E -> E + T
E -> T
T -> T * P
T -> P
P -> (E)
P -> (E [error]
P -> a
P -> @ [error]
a
是一个终端。
@
是空的。
方法2 :(仅允许启动规则的空规则)
S -> E
S -> @ [error]
E -> + [error]
E -> T + [error]
E -> + T [error]
E -> E + T
E -> T
T -> * [error]
T -> * P [error]
T -> P * [error]
T -> T * P
T -> P
P -> (E)
P -> (E [error]
P -> a
这是一个示例,用于显示使用每种方法的错误输入的最左侧推导。
输入: (a +
方法1 :
S
E
T
P
(E
(E + T
(T + T
(P + T
(a + T
(a + P
(a +
方法2 :
S
E
T
P
(E
(T +
(P +
(a +
方法2更难编码(考虑减法/一元否定算子。你不能只看减去A -> A - B
,先取出A
并在{{1上报告错误因为这对于一元运算符是有效的。)我今天早上为方法2编码只是为了发现我认为它有语法问题而且方法1中的空规则使事情变得更简单,代码方面,但我主要担心的是哪种方法会产生最少量的语法问题,因为程序员会创建如上所述的计算器描述。
答案 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