gpt4 book ai didi

java - ANTLR:解析引号字符串中的日期

转载 作者:搜寻专家 更新时间:2023-11-01 03:34:13 27 4
gpt4 key购买 nike

我在弄清楚如何解析语法中的日期时遇到了问题。

问题在于它与字符串共享其定义,但根据 Antlr 4 文档,它应该通过查看声明顺序来遵循优先级。

这是我的语法:

grammar formula;


/* entry point */
parse: expr EOF;

expr
: value # argumentArithmeticExpr
| l=expr operator=('*'|'/'|'%') r=expr # multdivArithmeticExpr // TODO: test the % operator
| l=expr operator=('+'|'-') r=expr # addsubtArithmeticExpr
| '-' expr # minusArithmeticExpr
| FUNCTION_NAME '(' (expr ( ',' expr )* ) ? ')'# functionExpr
| '(' expr ')' # parensArithmeticExpr
;

value
: number
| variable
| date
| string
| bool;

/* Atomes */

bool
: BOOL
;

variable
: '[' (~(']') | ' ')* ']'
;

date
: DQUOTE date_format DQUOTE
| QUOTE date_format QUOTE
;

date_format
: year=INT '-' month=INT '-' day=INT (hour=INT ':' minutes=INT ':' seconds=INT)?
;

string
: STRING_LITERAL
;


number
: ('+'|'-')? NUMERIC_LITERAL
;


/* lexemes de base */

QUOTE : '\'';
DQUOTE : '"';
MINUS : '-';
COLON : ':';
DOT : '.';
PIPE : '|';
BOOL : T R U E | F A L S E;

FUNCTION_NAME: IDENTIFIER ;

IDENTIFIER
: [a-zA-Z_] [a-zA-Z_0-9]* // TODO: do we more chars in this set?
;

NUMERIC_LITERAL
: DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )? // ex: 0.05e3
| '.' DIGIT+ ( E [-+]? DIGIT+ )? // ex: .05e3
;

INT: DIGIT+;

STRING_LITERAL
: '\'' ( ~'\'' | '\'\'' )* '\''
| '"' ( ~'"' | '""' )* '"'
;

WS: [ \t\n]+ -> skip;

UNEXPECTED_CHAR: . ;

fragment DIGIT: [0-9];
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');

这里的重要部分是:

value
: number
| variable
| date
| string
| bool;

date
: DQUOTE date_format DQUOTE
| QUOTE date_format QUOTE
;

date_format
: year=INT '-' month=INT '-' day=INT (hour=INT ':' minutes=INT ':' seconds=INT)?
;

我的语法需要这些东西:

  • "a quoted string" -> 给出一个string
  • "2015-03 TOTOTo" -> 给出了一个字符串,因为日期格式不匹配。
  • "2015-03-15" -> 给出一个 date 因为它匹配 DQUOTE INT '-' INT '-' INT DQUOTE

我(尝试过?)确保解析器在尝试匹配字符串之前尝试匹配日期:值:...|日期 |字符串| ...

但是当我使用 grun 实用程序(和我的单元测试......)时,我可以看到它将日期归类为字符串,就像它从不费心检查日期格式一样。

the ast

你能告诉我为什么会这样吗?我怀疑我声明语法规则的顺序有问题,但我尝试了一些排列但没有得到任何结果。

最佳答案

问题源于未能理解词法分析器在任何解析器规则被有效考虑之前运行完成。

这意味着,STRING_LITERAL 词法分析器规则将使用所有字符串,包括日期,并且仅输出 STRING_LITERAL 标记。 date 和相关的解析器子规则从未被解析器考虑过。

也许最小的解决方案是将 STRING_LITERAL 词法分析器规则修改为

STRING_LITERAL
: { notDateString() }?
( QUOTE .*? QUOTE
| DQUOTE .*? DQUOTE
)
;

notDateString 谓词需要 native 代码来执行日期格式和其他字符串之间的基本消歧。

另一种选择是将 STRING_LITERAL 规则完全提升到解析器。可行,但有点困惑,具体取决于是否需要在“真实”字符串中保留空格。

顺便说一句,您可能希望添加一个 token stream dump到您的标准单元测试系列。

关于java - ANTLR:解析引号字符串中的日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36503592/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com