ANTLR 解析字符串丢失字符?
ANTLR parsing string losing characters?
我有以下语法
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 查询 -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]
知道为什么会出现上述错误吗?
当点后有字符而不是 space 时,情况会变得更糟,因为字符丢失了。
2015 年 7 月 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 的规则分开,因为我使用它们可以轻松识别我正在编写的访问者的这些规则。
这个稍微清理过的版本应该有所帮助,但看起来您需要更多时间来阅读文档。强烈建议获取 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) 的右侧必须在词法分析器规则中。为了进行测试,您可以添加一个仅引用字符串规则的解析器规则。
我有以下语法
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 查询 -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]
知道为什么会出现上述错误吗?
当点后有字符而不是 space 时,情况会变得更糟,因为字符丢失了。
2015 年 7 月 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 的规则分开,因为我使用它们可以轻松识别我正在编写的访问者的这些规则。
这个稍微清理过的版本应该有所帮助,但看起来您需要更多时间来阅读文档。强烈建议获取 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) 的右侧必须在词法分析器规则中。为了进行测试,您可以添加一个仅引用字符串规则的解析器规则。