非プログラマーによって作成される 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 )
) が のみとして理解されることです(true or false)
。
パースツリーは次のとおりです。
では、これを解決する方法。どういうわけか文法を変更するか、実装ハックを使用する必要がありますか?
必要な場合に備えて、何か難しい例を示します。
(( 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 <> "")