我需要一个小技巧让我的解析器完全正常工作。 我使用antlr来解析布尔查询。
查询由元素组成,由ands,ors和nots链接在一起。
所以我可以有类似的东西:
"(P or not Q or R) or (( not A and B) or C)"
事情是,元素可以很长,通常采用以下形式:
a an_operator b
例如:
"New-York matches NY"
Trick,其中一个an_operator是“不喜欢”
所以我想修改我的词法分析器,以便不检查它之后没有类似的东西,以避免解析包含“not like”运算符的元素。
我目前的语法在这里:
// save it in a file called Logic.g
grammar Logic;
options {
output=AST;
}
// parser/production rules start with a lower case letter
parse
: expression EOF! // omit the EOF token
;
expression
: orexp
;
orexp
: andexp ('or'^ andexp)* // make `or` the root
;
andexp
: notexp ('and'^ notexp)* // make `and` the root
;
notexp
: 'not'^ atom // make `not` the root
| atom
;
atom
: ID
| '('! expression ')'! // omit both `(` andexp `)`
;
// lexer/terminal rules start with an upper case letter
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
任何帮助将不胜感激。 谢谢!
答案 0 :(得分:4)
这是一个可能的解决方案:
grammar Logic;
options {
output=AST;
}
tokens {
NOT_LIKE;
}
parse
: expression EOF!
;
expression
: orexp
;
orexp
: andexp (Or^ andexp)*
;
andexp
: fuzzyexp (And^ fuzzyexp)*
;
fuzzyexp
: (notexp -> notexp) ( Matches e=notexp -> ^(Matches $fuzzyexp $e)
| Not Like e=notexp -> ^(NOT_LIKE $fuzzyexp $e)
| Like e=notexp -> ^(Like $fuzzyexp $e)
)?
;
notexp
: Not^ atom
| atom
;
atom
: ID
| '('! expression ')'!
;
And : 'and';
Or : 'or';
Not : 'not';
Like : 'like';
Matches : 'matches';
ID : ('a'..'z' | 'A'..'Z')+;
Space : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};
将输入"A not like B or C like D and (E or not F) and G matches H"
解析为以下AST: