我们有一些非程序员编写的 vb6 代码片段(仅使用功能的子集)。这些被称为规则。对于编写这些的人来说,他们很难调试,所以有人写了一种附加的解析器来评估子表达式,从而更好地显示问题所在。
这个临时解析器非常糟糕,并且不能真正工作。所以我试图编写一个真正的解析器(因为我是手工编写的(没有解析器生成器我可以用 vb6 后端理解)我想使用递归体面的解析器)。我不得不对语法进行逆向工程,因为我可以找到任何东西。(最终我发现了一些东西http://www.notebar.com/GoldParserEngine.html但它的 LALR 和它的方式比我需要的要大)
这是VB子集的语法。
<Rule> ::= expr rule | e
<Expr> ::= ( expr )
| Not_List CompareExpr <and_or> expr
| Not_List CompareExpr
<and_or> ::= Or | And
<Not_List> ::= Not Not_List | e
<CompareExpr> ::= ConcatExpr comp CompareExpr
|ConcatExpr
<ConcatExpr> ::= term term_tail & ConcatExpr
|term term_tail
<term> ::= factor factor_tail
<term_tail> ::= add_op term term_tail | e
<factor> ::= add_op Value | Value
<factor_tail> ::= multi_op factor factor_tail | e
<Value> ::= ConstExpr | function | expr
<ConstExpr> ::= <bool> | number | string | Nothing
<bool> ::= True | False
<Nothing> ::= Nothing | Null | Empty
<function> ::= id | id ( ) | id ( arg_list )
<arg_list> ::= expr , arg_list | expr
<add_op> ::= + | -
<multi_op> ::= * | /
<comp> ::= > | < | <= | => | =< | >= | = | <>
总而言之,它工作得很好,这里有一些简单的例子:
my_function(1, 2 , 3)
好像
(Programm
(rule
(expr
(Not_List)
(CompareExpr
(ConcatExpr
(term
(factor
(value
(function
my_function
(arg_list
(expr
(Not_List)
(CompareExpr
(ConcatExpr (term (factor (value 1))) (term_tail))))
(arg_list
(expr
(Not_List)
(CompareExpr
(ConcatExpr (term (factor (value 2))) (term_tail))))
(arg_list
(expr
(Not_List)
(CompareExpr
(ConcatExpr (term (factor (value 3))) (term_tail))))
(arg_list))))))))
(term_tail))))
(rule)))
现在我的问题是什么?
如果你有这样的代码,(( true OR false ) AND true)
我有一个无限递归,但真正的问题是 (true OR false) AND true
(在第一个之后( expr )
)被理解为 only (true or false)
。
这是Parstree:
那么如何解决这个问题。我应该以某种方式更改语法还是使用一些实施技巧?
万一你需要它,一些很难的例子。
(( f1 OR f1 ) AND (( f3="ALL" OR f4="test" OR f5="ALL" OR f6="make" OR f9(1, 2) ) AND ( f7>1 OR f8>1 )) OR f8 <> "")