我有以下语法
grammar Lucene;
/*
* Parser Rules
*/
query : orExpr WHITESPACE* NEWLINE? EOF
;
orExpr : expr ((ORTOKEN | SPACE)? expr)* /* or exp */
;
expr : LPAREN orExpr RPAREN /* grouping */
| expr ANDTOKEN expr /* and exp */
| expr NOTTOKEN expr /* not exp */
| required
| prohibited
| proximity
| fuzzy
| boosted
| phrase
| term
;
proximity : phrase TILDE INT
;
fuzzy : term TILDE FLOAT?
;
boosted : (term | phrase) ACCENT (FLOAT | INT)
;
required : PLUSTOKEN WHITESPACE? term
;
prohibited : MINUSTOKEN WHITESPACE? term
;
term : (ALPHANUM+ ( '*' | '?' )? ALPHANUM*)
;
phrase : '"' ( ~'\\"' | . )*? '"'
;
/*
* Lexer Rules
*/
ALPHANUM : CHARACTER
| NUM
;
CHARACTER : 'a'..'z'
| 'A'..'Z'
;
FLOAT : NUM* '.' NUM+
;
INT : NUM+
;
NUM : '0'..'9'
;
LPAREN : '('
;
RPAREN : ')'
;
ANDTOKEN : ' AND '
;
NOTTOKEN : ' NOT '
| ' !'
;
ORTOKEN : ' OR '
;
PLUSTOKEN : '+'
;
MINUSTOKEN : '-'
;
TILDE : '~'
;
ACCENT : '^'
;
SPACE : ' '
;
CR : '\r'
| '\n'
;
WHITESPACE : ( SPACE | '\t' ) -> skip ;
NEWLINE : ('\r'?'\n'|'\r') -> skip;
目的是使用短语规则处理字符串文字,但是当字符串包含“。”等字符时或“:”我在检查TestRig时遇到以下错误(使用java org.antlr.v4.gui.TestRig Lucene query -gui):
line 1:15 token recognition error at: '. '
line 1:28 token recognition error at: ':'
[@0,0:0='"',<9>,1:0]
[@1,1:1='P',<4>,1:1]
[@2,2:2='r',<4>,1:2]
[@3,3:3='o',<4>,1:3]
[@4,4:4='v',<4>,1:4]
[@5,5:5='i',<4>,1:5]
[@6,6:6='d',<4>,1:6]
[@7,7:7='e',<4>,1:7]
[@8,8:8='d',<4>,1:8]
[@9,9:9=' ',<19>,1:9]
[@10,10:10='t',<4>,1:10]
[@11,11:11='e',<4>,1:11]
[@12,12:12='r',<4>,1:12]
[@13,13:13='m',<4>,1:13]
[@14,14:14='s',<4>,1:14]
[@15,17:17='F',<4>,1:17]
[@16,18:18='o',<4>,1:18]
[@17,19:19='r',<4>,1:19]
[@18,20:20=' ',<19>,1:20]
[@19,21:21='e',<4>,1:21]
[@20,22:22='x',<4>,1:22]
[@21,23:23='a',<4>,1:23]
[@22,24:24='m',<4>,1:24]
[@23,25:25='p',<4>,1:25]
[@24,26:26='l',<4>,1:26]
[@25,27:27='e',<4>,1:27]
[@26,29:29=' ',<19>,1:29]
[@27,30:30='a',<4>,1:30]
[@28,31:31='t',<4>,1:31]
[@29,32:32='e',<4>,1:32]
[@30,33:33='r',<4>,1:33]
[@31,34:34='m',<4>,1:34]
[@32,35:35='"',<9>,1:35]
[@33,38:37='<EOF>',<-1>,2:0]
知道为什么会出现上述错误吗?
当字符丢失时,点后面有字符而不是空格会变得更糟。
2015年10月10日更新
已修复:我修正了更新短语规则的问题(通过@GRosengberg进行了一些推荐的更改,但并非所有语法都没有按预期工作)
phrase
: LITERAL
;
LITERAL
: '"' ( '\\"' | .)*? '"'
;
其中给出了期望的结果,也更新了语法以接受其余的规则,后来我改变了初始规则来解决运算符优先级问题,但现在我得到了相互左递归错误。冲突的规则如下:
expr : orExpr
| andExpr
| prohibited
| required
| boosted
| fuzzy
| spanNear
| proximity
| term
| phrase
| groupExpr
;
orExpr : expr ((WS+ | WS+ OR WS+) orExpr)+
| expr
;
andExpr : expr (WS+ AND WS+ andExpr)+
| expr (WS+ notExpr)+
| expr
;
notExpr : NOT WS+ expr
;
有关如何解决此问题的任何想法?我已经为orExpr和andExpr分离了规则,因为我使用它们来轻松地识别我正在写的访问者的这些规则。
答案 0 :(得分:0)
这个有点清理的版本应该有所帮助,但看起来你需要更多的时间来使用文档。强烈建议您使用TDAR。
grammar Lucene;
query : expr+ EOF ;
expr : LPAREN orExpr RPAREN /* grouping */
| expr ANDTOKEN expr /* and exp */
| expr NOTTOKEN expr /* not exp */
| expr ORTOKEN expr /* or exp */
| required
| prohibited
| proximity
| fuzzy
| boosted
| phrase
| term
;
proximity : phrase TILDE INT ;
fuzzy : term TILDE FLOAT? ;
boosted : (term | phrase) ACCENT (FLOAT | INT) ;
required : PLUSTOKEN term ;
prohibited : MINUSTOKEN term ;
term : alphanum+ ( STAR | QMARK )? alphanum* ;
alphanum : CHARACTER | NUM ;
phrase : STRING ;
ANDTOKEN : ' AND ' ;
NOTTOKEN : ' NOT ' | ' !' ;
ORTOKEN : ' OR ' ;
FLOAT : NUM* '.' NUM+ ;
INT : NUM+ ;
STRING : '"' .*? '"' ;
WHITESPACE : [ \t\r\n]+ -> skip;
CHARACTER : 'a'..'z' | 'A'..'Z' ;
NUM : '0'..'9' ;
LPAREN : '(' ;
RPAREN : ')' ;
PLUSTOKEN : '+' ;
MINUSTOKEN : '-' ;
STAR : '*' ;
QMARK : '?' ;
BANG : '!' ;
TILDE : '~' ;
ACCENT : '^' ;
简化expr
规则以包含or
变体 - 可能会遇到左递归问题,并将其分开。
如果将alphanum
保留为词法分析器规则(ALPHANUM),则解析器只能看到ALPHANUM标记 - 解析器永远不会看到任何离散的CHARACTER和NUM标记。
同样,由于你在词法分析器中跳过WHITESPACE,解析器永远不会看到这些标记 - 它们不能用于解析器规则。
字符串规则(STRING)的rhs必须是词法规则。对于测试,您可以添加仅引用字符串规则的解析器规则。