我使用了一些解析器和词法分析器生成工具(类似于Lex和野牛,但对于C#)生成解析字符串转换为抽象语法树以后可以评估的计划。
我想要做的错误恢复(即报告中产生的抽象句树,有缺失的令牌和这样)。 我想到了两种方法来构建生成的语法,我想知道哪种方法比较好/比较灵活/不会有冲突 (中不间断地和.lex文件是基于计算器的描述产生的)。
计算器描述允许用户指定终端/正则表达式的及其对运营商和关联性安置。 因此,像:
grammar.AddTerminal("Plus", "\\+").
AddNonTerminal(new NonTerminal("Add", Associativity.LeftToRight).
AddTerminal("Expression").
AddTerminal("Plus").
AddTerminal("Expression"));
(优先通过该命令指定Terminal
的和NonTerminal
的加入。 "Add"
是通过反射发现了一个方法的名称,基本上它告诉非终结叫什么操作的抽象语法树。 )
方法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
,并在报告错误A -> - B
,因为这是有效的单目运算符)。我编码方法2今天早上才发现,我认为它有语法问题和空规则在方案1使事情变得更简单,代码明智的,但我主要关注的是哪种方法会产生的语法问题程序员量最少创建计算器描述如上所述。