首页 > 解决方案 > 输入 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 生成错误。

在输入选项卡 [key] 中没有可行的选择

我能做些什么来解决这个问题?

标签: javaantlr4

解决方案


Firsttab [key]不会产生KEY您想要的令牌,原因有两个:

  1. 它包含空格并且KEY不允许任何空格。解决这个问题的最好方法是KEY从词法分析器中删除规则,然后将其转换为解析器规则(这意味着您还需要将[]转换为自己的标记)。然后输入中的空白将位于标记之间,因此成功跳过。
  2. key实际上不是 中列出的单词之一NAMES

然后另一个问题是in被识别为ID令牌,而不是IN令牌。这是因为两者IDIN都会产生相同长度的匹配,在这种情况下,首先列出的规则优先。因此,您应该ID在所有关键字之后定义,否则关键字将永远不会匹配。


推荐阅读