首页 > 解决方案 > 外部输入 '-' 期望 {DECIMAL, '+', '-'}

问题描述

使用最新的 Antlr 运行时 4.6.6,我正在尝试处理带符号的数字,但不知道我做错了什么。从 TSQL 语法中清除样本,我使用以下内容来解析有符号数:

time_expression
: interval=(YEARS|MONTHS|DAYS|HOURS|MINUTES) '(' signed_decimal ')'
;

signed_decimal
:sign? DECIMAL
;

它适用于无符号数字,但是当我尝试解析时:Test > MONTHS(-537)我收到此错误:extraneous input '-' expecting {DECIMAL, '+', '-'}

这是我的词法分析器语法:

lexer grammar QLexer;
@modifier{internal}
 
FROM:                                  'FROM';
IN:                                    'IN';
NULL:                                  'NULL';
OR:                                    'OR';
IS:                                    'IS';
AND:                                   'AND';
NOT:                                   'NOT';
PARENT:                                'PARENT';
YEARS:                                 'YEARS';
MONTHS:                                'MONTHS';
DAYS:                                  'DAYS';
HOURS:                                 'HOURS';
MINUTES:                               'MINUTES';
HASTAG:                                'HASTAG';
PARAGRAPH:          (NEWLINE NEWLINE);
 
 
TAB:             [ \t\r\n]+    -> skip;
// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/slash-star-comment-transact-sql
COMMENT:            '/*' (COMMENT | .)*? '*/' -> channel(HIDDEN);
LINE_COMMENT:       '--' ~[\r\n]* -> channel(HIDDEN);
 
 
 
// TODO: ID can be not only Latin.
EMBEDED_SQL:        '{' (.)*? '}';
DOUBLE_QUOTE_ID:    '"' ~'"'+ '"';
SINGLE_QUOTE:       '\'';
SQUARE_BRACKET_ID:  '[' ~']'+ ']';
LOCAL_ID:           '@' ID;
TEST_ID:            '#' ID;
DECIMAL:             DEC_DIGIT+;
ID:                  ([A-Za-z0-9_])+;
STRING:              'N'? '\'' (~'\'' | '\'\'')* '\'';
BINARY:              '0' 'X' HEX_DIGIT*;
 
 
 
EQUAL:               '=';
 
GREATER:             '>';
LESS:                '<';
EXCLAMATION:         '!';
 
PLUS_ASSIGN:         '+=';
MINUS_ASSIGN:        '-=';
MULT_ASSIGN:         '*=';
DIV_ASSIGN:          '/=';
MOD_ASSIGN:          '%=';
AND_ASSIGN:          '&=';
XOR_ASSIGN:          '^=';
OR_ASSIGN:           '|=';
 
ARITHMETIC:           '*' | '/'|'+' | '-'; 
 
DOUBLE_BAR:          '||';
DOT:                 '.';
UNDERLINE:           '_';
AT:                  '@';
SHARP:               '#';
DOLLAR:              '$';
LR_BRACKET:          '(';
RR_BRACKET:          ')';
COMMA:               ',';
SEMI:                ';';
COLON:               ':';
STAR:                '*';
DIVIDE:              '/';
MODULE:              '%';
PLUS:                '+';
MINUS:               '-';
BIT_NOT:             '~';
BIT_OR:              '|';
BIT_AND:             '&';
BIT_XOR:             '^';
NUM : '[0-9]+ ('.' [0-9]+)?';
SIGNED_NUMBER:       '^-?[1-9][0-9]{0,2}$';
 
UNSIGNED_INT : ('0' | '1'..'9' '0'..'9'*);
 
HEX_DIGIT:    [0-9A-F];
DEC_DIGIT:    [0-9];
 
//fragment Exponent : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
 
fragment LETTER:       [A-Z_];
//fragment DEC_DOT_DEC:  (DEC_DIGIT+ '.' DEC_DIGIT+ |  DEC_DIGIT+ '.' | '.' DEC_DIGIT+);
//fragment HEX_DIGIT:    [0-9A-F];
//fragment DEC_DIGIT:    [0-9];
 
fragment NEWLINE: '\r'? '\n';

标签: .net-coreantlr4

解决方案


你的规则:

NUM           : '[0-9]+ ('.' [0-9]+)?';
SIGNED_NUMBER : '^-?[1-9][0-9]{0,2}$';

匹配文字字符串。你的意思可能是这样的:

NUM           : [0-9]+ ('.' [0-9]+)?;
SIGNED_NUMBER : '-'? [1-9] ([0-9] [0-9]?)?;

你可能也想让signed_decimalmatch SIGNED_NUMBER

signed_decimal
 : sign? DECIMAL
 | SIGNED_NUMBER
 ;

推荐阅读