ANTLR 匹配字符串中的 DateTIme
ANTLR Match DateTIme in String
我编写了以下用于从给定字符串解析 DateTime 的语法
datetime: INT SEPARATOR month SEPARATOR INT4
| INT SEPARATOR month SEPARATOR INT4;
month:
JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| DEC;
STRING: [a-zA-Z][a-zA-Z]+;
NUMBER: [0-9]+;
INT4: DIGIT DIGIT DIGIT DIGIT;
INT: DIGIT+;
DIGIT: ['0'-'9'];
DQUOTE : '"';
JAN: [Jj][Aa][Nn];
FEB: [Ff][Ee][Bb];
MAR: [Mm][Aa][Rr];
APR: [Aa][Pp][Rr];
MAY: [Mm][Aa][Yy];
JUN: [Jj][Uu][Nn];
JUL: [Jj][Uu][Ll];
AUG: [Aa][Uu][Gg];
SEP: [Ss][Ee][Pp];
OCT: [Oo][Cc][Tt];
NOV: [Nn][Oo][Vv];
DEC: [Dd][Ee][Cc];
SEPARATOR: '-';
WS: [ \n\t\r]+ -> skip;
当我尝试匹配以下字符串时
new teatime at 23-SEP-2013 for Santosh Singh and 3 guests
我在 ANTLR 输出中收到以下错误
line 1:15 mismatched input '23' expecting INT
首先,DIGIT: ['0'-'9'];
规则不正确,应该是:DIGIT: [0-9];
每当你得到意想不到的结果时,首先转储你的词法分析器正在创建的标记,看看它们是否是你希望解析器使用的标记。对于您的语法,这将是以下标记:
STRING `new`
STRING `teatime`
STRING `at`
NUMBER `23`
SEPARATOR `-`
STRING `SEP`
SEPARATOR `-`
NUMBER `2013`
STRING `for`
STRING `Santosh`
STRING `Singh`
STRING `and`
NUMBER `3`
STRING `guests`
如您所见,有几处出错了:
- 从未创建过
INT
标记,而您的解析器需要这样的标记。这是因为以下规则(及其顺序):
NUMBER : [0-9]+;
INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;
DIGIT : [0-9];
对于输入3
,可以匹配规则NUMBER
、INT
和DIGIT
。每当 ANTLR 的词法分析器可以构造超过 1 个标记时,首先定义的标记(词法分析器规则)“获胜”。因此,单个数字令牌或任意数量的数字令牌将始终成为 NUMBER
令牌。 INT4
、INT
和 DIGIT
将永远不会被创建,无论解析器是否试图匹配这些标记中的任何一个。词法分析器独立于解析器工作。你对此无能为力。
- 月份永远不会匹配,它们都是
STRING
标记。与上面的问题相同:"SEP"
可以通过 STRING
规则和 SEP
规则匹配,但是由于 STRING
在 SEP
之前定义,定义第一个“获胜”的人。
像这样重新排序语法:
grammar T;
parse
: (datetime | text)+ EOF
;
text
: STRING
| month
| INT
;
datetime
: INT SEPARATOR month SEPARATOR INT4
| INT SEPARATOR month SEPARATOR INT4
;
month
: JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| DEC
;
JAN : [Jj][Aa][Nn];
FEB : [Ff][Ee][Bb];
MAR : [Mm][Aa][Rr];
APR : [Aa][Pp][Rr];
MAY : [Mm][Aa][Yy];
JUN : [Jj][Uu][Nn];
JUL : [Jj][Uu][Ll];
AUG : [Aa][Uu][Gg];
SEP : [Ss][Ee][Pp];
OCT : [Oo][Cc][Tt];
NOV : [Nn][Oo][Vv];
DEC : [Dd][Ee][Cc];
STRING : [a-zA-Z][a-zA-Z]+;
INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;
DQUOTE : '"';
SEPARATOR : '-';
WS: [ \n\t\r]+ -> skip;
fragment DIGIT : [0-9];
应该正确匹配您的输入。
我编写了以下用于从给定字符串解析 DateTime 的语法
datetime: INT SEPARATOR month SEPARATOR INT4
| INT SEPARATOR month SEPARATOR INT4;
month:
JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| DEC;
STRING: [a-zA-Z][a-zA-Z]+;
NUMBER: [0-9]+;
INT4: DIGIT DIGIT DIGIT DIGIT;
INT: DIGIT+;
DIGIT: ['0'-'9'];
DQUOTE : '"';
JAN: [Jj][Aa][Nn];
FEB: [Ff][Ee][Bb];
MAR: [Mm][Aa][Rr];
APR: [Aa][Pp][Rr];
MAY: [Mm][Aa][Yy];
JUN: [Jj][Uu][Nn];
JUL: [Jj][Uu][Ll];
AUG: [Aa][Uu][Gg];
SEP: [Ss][Ee][Pp];
OCT: [Oo][Cc][Tt];
NOV: [Nn][Oo][Vv];
DEC: [Dd][Ee][Cc];
SEPARATOR: '-';
WS: [ \n\t\r]+ -> skip;
当我尝试匹配以下字符串时
new teatime at 23-SEP-2013 for Santosh Singh and 3 guests
我在 ANTLR 输出中收到以下错误
line 1:15 mismatched input '23' expecting INT
首先,DIGIT: ['0'-'9'];
规则不正确,应该是:DIGIT: [0-9];
每当你得到意想不到的结果时,首先转储你的词法分析器正在创建的标记,看看它们是否是你希望解析器使用的标记。对于您的语法,这将是以下标记:
STRING `new`
STRING `teatime`
STRING `at`
NUMBER `23`
SEPARATOR `-`
STRING `SEP`
SEPARATOR `-`
NUMBER `2013`
STRING `for`
STRING `Santosh`
STRING `Singh`
STRING `and`
NUMBER `3`
STRING `guests`
如您所见,有几处出错了:
- 从未创建过
INT
标记,而您的解析器需要这样的标记。这是因为以下规则(及其顺序):
NUMBER : [0-9]+;
INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;
DIGIT : [0-9];
对于输入3
,可以匹配规则NUMBER
、INT
和DIGIT
。每当 ANTLR 的词法分析器可以构造超过 1 个标记时,首先定义的标记(词法分析器规则)“获胜”。因此,单个数字令牌或任意数量的数字令牌将始终成为 NUMBER
令牌。 INT4
、INT
和 DIGIT
将永远不会被创建,无论解析器是否试图匹配这些标记中的任何一个。词法分析器独立于解析器工作。你对此无能为力。
- 月份永远不会匹配,它们都是
STRING
标记。与上面的问题相同:"SEP"
可以通过STRING
规则和SEP
规则匹配,但是由于STRING
在SEP
之前定义,定义第一个“获胜”的人。
像这样重新排序语法:
grammar T;
parse
: (datetime | text)+ EOF
;
text
: STRING
| month
| INT
;
datetime
: INT SEPARATOR month SEPARATOR INT4
| INT SEPARATOR month SEPARATOR INT4
;
month
: JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| DEC
;
JAN : [Jj][Aa][Nn];
FEB : [Ff][Ee][Bb];
MAR : [Mm][Aa][Rr];
APR : [Aa][Pp][Rr];
MAY : [Mm][Aa][Yy];
JUN : [Jj][Uu][Nn];
JUL : [Jj][Uu][Ll];
AUG : [Aa][Uu][Gg];
SEP : [Ss][Ee][Pp];
OCT : [Oo][Cc][Tt];
NOV : [Nn][Oo][Vv];
DEC : [Dd][Ee][Cc];
STRING : [a-zA-Z][a-zA-Z]+;
INT4 : DIGIT DIGIT DIGIT DIGIT;
INT : DIGIT+;
DQUOTE : '"';
SEPARATOR : '-';
WS: [ \n\t\r]+ -> skip;
fragment DIGIT : [0-9];
应该正确匹配您的输入。