У нас есть небольшие фрагменты кода vb6 (единственное использование подмножества функций), который запрограммирован не программистами.Это так называемые правила.Людям, пишущим их, их сложно отлаживать, поэтому кто-то написал своего рода анализатор add hoc, чтобы иметь возможность оценивать подвыражения и тем самым лучше показывать, где проблема.
Этот синтаксический анализатор addhoc очень плох и недействительно работает волл.Поэтому я пытаюсь написать настоящий парсер (потому что я пишу его вручную (нет генератора парсера, который я мог бы понять с помощью бэкэндов 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)
.
Вот Parstree: ![Parse Tree](https://i.stack.imgur.com/wtdjo.jpg)
Так как это решить.Должен ли я как-то изменить грамматику или использовать какой-нибудь хакерский имплментатор?
Что-то сложное, например, на случай, если оно вам понадобится.
(( 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 <> "")