输入 ANTLR4 没有可行的替代方案
no viable alternative at input ANTLR4
我正在设计一种允许您对数据进行谓词的语言。这是我的词法分析器。
lexer grammar Studylexer;
fragment LETTER : [A-Za-z];
fragment DIGIT : [0-9];
fragment TWODIGIT : DIGIT DIGIT;
fragment MONTH: ('0' [1-9] | '1' [0-2]);
fragment DAY: ('0' [1-9] | '1' [1-9] | '2' [1-9] | '3' [0-1]);
TIMESTAMP: TWODIGIT ':' TWODIGIT; // représentation de la timestamp
DATE : TWODIGIT TWODIGIT MONTH DAY; // représentation de la date
ID : LETTER+; // match identifiers
STRING : '"' ( ~ '"' )* '"' ; // match string content
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS : [ \t]+ -> skip ; // toss out whitespace
LIST: ( LISTSTRING | LISTDATE | LISTTIMESTAMP ) ; // list of variabels;
// list of operators
GT: '>';
LT: '<';
GTEQ: '>=';
LTEQ:'<=';
EQ: '=';
IN: 'in';
fragment LISTSTRING: STRING ',' STRING (',' STRING)*; // list of strings
fragment LISTDATE : DATE ',' DATE (',' DATE)*; // list of dates
fragment LISTTIMESTAMP:TIMESTAMP ',' TIMESTAMP (',' TIMESTAMP )*; // list of timestamps
NAMES: 'filename' | 'timestamp' | 'tso' | 'region' | 'processType' | 'businessDate' | 'lastModificationDate'; // name of variables in the where block
KEY: ID '[' NAMES ']' | ID '.' NAMES; // predicat key
这是我语法的一部分。
expr: KEY op = ('>' | '<') value = ( DATE | TIMESTAMP ) NEWLINE # exprGTORLT
| KEY op = ('>='| '<=') value = ( DATE | TIMESTAMP ) NEWLINE # exprGTEQORLTEQ
| KEY '=' value = ( STRING | DATE | TIMESTAMP ) NEWLINE # exprEQ
| KEY 'in' LIST NEWLINE #exprIn
当我做一个谓词时。
tab [key] in "value1", "value2"
ANTLR 生成错误。
no viable alternative at input tab [key] in
我该怎么做才能解决这个问题?
首先 tab [key]
没有像您希望的那样生成 KEY
令牌,原因有两个:
- 它包含 space 并且
KEY
不允许任何 space。解决这个问题的最好方法是从词法分析器中删除 KEY
规则,而是将其转换为解析器规则(这意味着您还需要将 [
和 ]
转换为它们自己的标记).然后输入中的白色 space 将位于标记之间,从而成功跳过。
key
实际上不是 NAMES
中列出的单词之一。
然后另一个问题是 in
被识别为 ID
标记,而不是 IN
标记。这是因为 ID
和 IN
都会产生相同长度的匹配项,在这种情况下,首先列出的规则优先。所以你应该在所有关键字之后定义 ID
否则关键字永远不会被匹配。
我正在设计一种允许您对数据进行谓词的语言。这是我的词法分析器。
lexer grammar Studylexer;
fragment LETTER : [A-Za-z];
fragment DIGIT : [0-9];
fragment TWODIGIT : DIGIT DIGIT;
fragment MONTH: ('0' [1-9] | '1' [0-2]);
fragment DAY: ('0' [1-9] | '1' [1-9] | '2' [1-9] | '3' [0-1]);
TIMESTAMP: TWODIGIT ':' TWODIGIT; // représentation de la timestamp
DATE : TWODIGIT TWODIGIT MONTH DAY; // représentation de la date
ID : LETTER+; // match identifiers
STRING : '"' ( ~ '"' )* '"' ; // match string content
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS : [ \t]+ -> skip ; // toss out whitespace
LIST: ( LISTSTRING | LISTDATE | LISTTIMESTAMP ) ; // list of variabels;
// list of operators
GT: '>';
LT: '<';
GTEQ: '>=';
LTEQ:'<=';
EQ: '=';
IN: 'in';
fragment LISTSTRING: STRING ',' STRING (',' STRING)*; // list of strings
fragment LISTDATE : DATE ',' DATE (',' DATE)*; // list of dates
fragment LISTTIMESTAMP:TIMESTAMP ',' TIMESTAMP (',' TIMESTAMP )*; // list of timestamps
NAMES: 'filename' | 'timestamp' | 'tso' | 'region' | 'processType' | 'businessDate' | 'lastModificationDate'; // name of variables in the where block
KEY: ID '[' NAMES ']' | ID '.' NAMES; // predicat key
这是我语法的一部分。
expr: KEY op = ('>' | '<') value = ( DATE | TIMESTAMP ) NEWLINE # exprGTORLT
| KEY op = ('>='| '<=') value = ( DATE | TIMESTAMP ) NEWLINE # exprGTEQORLTEQ
| KEY '=' value = ( STRING | DATE | TIMESTAMP ) NEWLINE # exprEQ
| KEY 'in' LIST NEWLINE #exprIn
当我做一个谓词时。
tab [key] in "value1", "value2"
ANTLR 生成错误。
no viable alternative at input tab [key] in
我该怎么做才能解决这个问题?
首先 tab [key]
没有像您希望的那样生成 KEY
令牌,原因有两个:
- 它包含 space 并且
KEY
不允许任何 space。解决这个问题的最好方法是从词法分析器中删除KEY
规则,而是将其转换为解析器规则(这意味着您还需要将[
和]
转换为它们自己的标记).然后输入中的白色 space 将位于标记之间,从而成功跳过。 key
实际上不是NAMES
中列出的单词之一。
然后另一个问题是 in
被识别为 ID
标记,而不是 IN
标记。这是因为 ID
和 IN
都会产生相同长度的匹配项,在这种情况下,首先列出的规则优先。所以你应该在所有关键字之后定义 ID
否则关键字永远不会被匹配。