为什么在pase树中,ANTLR保持输入不匹配?

为什么在pase树中,ANTLR保持输入不匹配?,antlr,antlr4,Antlr,Antlr4,我是ANTLR4新手,我正在尝试以一种简单的形式可视化文本输入的解析树: grammar Expr; contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*; asset: '$'| 'TND' | 'USD'; quantity:Q; beneficiary: B; send_date : day SLASH month SLASH year; day: D ; month:

我是ANTLR4新手,我正在尝试以一种简单的形式可视化文本输入的解析树:

grammar Expr;
contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*;
asset: '$'| 'TND' | 'USD';
quantity:Q;
beneficiary: B;
send_date : day SLASH month SLASH year;
day: D ;
month: M ;
year: Y ;
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
Q : DIGITO DIGITZ*|DIGITO DIGITZ* POINT DIGITZ*;
D : DIGIT0 DIGITO|(DIGIT1|DIGIT2)DIGITZ|DIGIT3(DIGIT0|DIGIT1);
M : DIGIT0 DIGITO| DIGIT1(DIGIT0|DIGIT1|DIGIT2);
Y : DIGIT2 DIGIT0((DIGIT1(DIGIT7|DIGIT8|DIGIT9))|(DIGIT2 DIGITZ));
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
DIGITZ : [0-9];
DIGITO : [1-9];
DIGIT0 : [0];
DIGIT1 : [1];
DIGIT2 : [2];
DIGIT3 : [3];
DIGIT4 : [4];
DIGIT5 : [5];
DIGIT6 : [6];
DIGIT7 : [7];
DIGIT8 : [8];
DIGIT9 : [9];
SLASH:'/';
POINT:'.'|',';
WS : (' ' | '\t' |'\n' |'\r' )+ ;
但它始终与
发送日期不匹配,如您在此处所见:


我知道这是一个非常复杂的数字语法,我只是想要一些控制01这是一个非常复杂的数字语法。也许你可以简化:

day: NUMBER ;
month: NUMBER ;
year: NUMBER ;

NUMBER : DIGITZ+ ;
DIGITZ : [0-9];
您可以在代码中强制执行语义,比如将年份限制为[2017…2020]或其他任何内容。只是个主意。简化通常会有帮助,然后你可以从那里加强它,知道如果你犯了错误,你总是可以恢复到至少可以工作的东西

编辑:

你的语法不起作用的原因是因为这个月被折成了一天:

[@0,0:0='I',<'I'>,1:0]
[@1,1:1=' ',<WS>,1:1]
[@2,2:5='send',<'send'>,1:2]
[@3,6:6=' ',<WS>,1:6]
[@4,7:9='300',<Q>,1:7]
[@5,10:10=' ',<WS>,1:10]
[@6,11:11='$',<'$'>,1:11]
[@7,12:12=' ',<WS>,1:12]
[@8,13:14='to',<'to'>,1:13]
[@9,15:15=' ',<WS>,1:15]
[@10,16:20='Ahmed',<B>,1:16]
[@11,21:21=' ',<WS>,1:21]
[@12,22:23='on',<'on'>,1:22]
[@13,24:24=' ',<WS>,1:24]
[@14,25:26='03',<D>,1:25]
[@15,27:27='/',<'/'>,1:27]
[@16,28:29='07',<D>,1:28]  <-- see, this is being lexed as a D (day)
[@17,30:30='/',<'/'>,1:30]
[@18,31:34='2017',<Q>,1:31] <-- and this is being lexed as a Q (quantity)
[@19,35:36='\r\n',<WS>,1:35]
[@20,37:36='<EOF>',<EOF>,2:0]
line 1:28 mismatched input '05' expecting M
line 1:31 mismatched input '2017' expecting Y
改进: 1.更好地处理空白,更加传统。 2.简化的数字语法。 3.它起作用了

[@0,0:0='I',<'I'>,1:0]
[@1,2:5='send',<'send'>,1:2]
[@2,7:9='300',<NUMBER>,1:7]
[@3,11:11='$',<'$'>,1:11]
[@4,13:14='to',<'to'>,1:13]
[@5,16:20='Ahmed',<B>,1:16]
[@6,22:23='on',<'on'>,1:22]
[@7,25:34='03/07/2017',<DATE>,1:25]
[@8,37:36='<EOF>',<EOF>,2:0]
[@0,0:0='I',1:0]
[@1,2:5='send',1:2]
[@2,7:9='300',,1:7]
[@3,11:11='$',,1:11]
[@4,13:14='to',1:13]
[@5,16:20='Ahmed',1:16]
[@6,22:23='on',1:22]
[@7,25:34='03/07/2017',,1:25]
[@8,37:36='',,2:0]

问题:我简化了用十进制数表示数量的能力。你可以随心所欲地把它加回去。

这是一个非常复杂的数字语法。也许你可以简化:

day: NUMBER ;
month: NUMBER ;
year: NUMBER ;

NUMBER : DIGITZ+ ;
DIGITZ : [0-9];
您可以在代码中强制执行语义,比如将年份限制为[2017…2020]或其他任何内容。只是个主意。简化通常会有帮助,然后你可以从那里加强它,知道如果你犯了错误,你总是可以恢复到至少可以工作的东西

编辑:

你的语法不起作用的原因是因为这个月被折成了一天:

[@0,0:0='I',<'I'>,1:0]
[@1,1:1=' ',<WS>,1:1]
[@2,2:5='send',<'send'>,1:2]
[@3,6:6=' ',<WS>,1:6]
[@4,7:9='300',<Q>,1:7]
[@5,10:10=' ',<WS>,1:10]
[@6,11:11='$',<'$'>,1:11]
[@7,12:12=' ',<WS>,1:12]
[@8,13:14='to',<'to'>,1:13]
[@9,15:15=' ',<WS>,1:15]
[@10,16:20='Ahmed',<B>,1:16]
[@11,21:21=' ',<WS>,1:21]
[@12,22:23='on',<'on'>,1:22]
[@13,24:24=' ',<WS>,1:24]
[@14,25:26='03',<D>,1:25]
[@15,27:27='/',<'/'>,1:27]
[@16,28:29='07',<D>,1:28]  <-- see, this is being lexed as a D (day)
[@17,30:30='/',<'/'>,1:30]
[@18,31:34='2017',<Q>,1:31] <-- and this is being lexed as a Q (quantity)
[@19,35:36='\r\n',<WS>,1:35]
[@20,37:36='<EOF>',<EOF>,2:0]
line 1:28 mismatched input '05' expecting M
line 1:31 mismatched input '2017' expecting Y
改进: 1.更好地处理空白,更加传统。 2.简化的数字语法。 3.它起作用了

[@0,0:0='I',<'I'>,1:0]
[@1,2:5='send',<'send'>,1:2]
[@2,7:9='300',<NUMBER>,1:7]
[@3,11:11='$',<'$'>,1:11]
[@4,13:14='to',<'to'>,1:13]
[@5,16:20='Ahmed',<B>,1:16]
[@6,22:23='on',<'on'>,1:22]
[@7,25:34='03/07/2017',<DATE>,1:25]
[@8,37:36='<EOF>',<EOF>,2:0]
[@0,0:0='I',1:0]
[@1,2:5='send',1:2]
[@2,7:9='300',,1:7]
[@3,11:11='$',,1:11]
[@4,13:14='to',1:13]
[@5,16:20='Ahmed',1:16]
[@6,22:23='on',1:22]
[@7,25:34='03/07/2017',,1:25]
[@8,37:36='',,2:0]

问题:我简化了用十进制数表示数量的能力。您可以根据需要将其添加回。

出现问题的原因是您的语法不明确。07年可与D相匹敌,2017年可与Q相匹敌

您可以这样修复它:

grammar Expr;
contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*;
asset: '$'| 'TND' | 'USD';
quantity:Q;
beneficiary: B;
send_date : day month year ;
day: D ;
month:  M ;
year: Y ;

D : DIGIT0 DIGITO|(DIGIT1|DIGIT2)DIGITZ|DIGIT3(DIGIT0|DIGIT1);
M : SLASH (DIGIT0 DIGITO| DIGIT1(DIGIT0|DIGIT1|DIGIT2));
Y : SLASH (DIGIT2 DIGIT0((DIGIT1(DIGIT7|DIGIT8|DIGIT9))|(DIGIT2 DIGITZ)));
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
Q : DIGITO DIGITZ*|DIGITO DIGITZ* POINT DIGITZ*;
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
DIGITZ : [0-9];
DIGITO : [1-9];
DIGIT0 : [0];
DIGIT1 : [1];
DIGIT2 : [2];
DIGIT3 : [3];
DIGIT4 : [4];
DIGIT5 : [5];
DIGIT6 : [6];
DIGIT7 : [7];
DIGIT8 : [8];
DIGIT9 : [9];
SLASH:'/';
POINT:'.'|',';
WS : (' ' | '\t' |'\n' |'\r' )+ ;

发生问题的原因是您的语法不明确。07年可与D相匹敌,2017年可与Q相匹敌

您可以这样修复它:

grammar Expr;
contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*;
asset: '$'| 'TND' | 'USD';
quantity:Q;
beneficiary: B;
send_date : day month year ;
day: D ;
month:  M ;
year: Y ;

D : DIGIT0 DIGITO|(DIGIT1|DIGIT2)DIGITZ|DIGIT3(DIGIT0|DIGIT1);
M : SLASH (DIGIT0 DIGITO| DIGIT1(DIGIT0|DIGIT1|DIGIT2));
Y : SLASH (DIGIT2 DIGIT0((DIGIT1(DIGIT7|DIGIT8|DIGIT9))|(DIGIT2 DIGITZ)));
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
Q : DIGITO DIGITZ*|DIGITO DIGITZ* POINT DIGITZ*;
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
DIGITZ : [0-9];
DIGITO : [1-9];
DIGIT0 : [0];
DIGIT1 : [1];
DIGIT2 : [2];
DIGIT3 : [3];
DIGIT4 : [4];
DIGIT5 : [5];
DIGIT6 : [6];
DIGIT7 : [7];
DIGIT8 : [8];
DIGIT9 : [9];
SLASH:'/';
POINT:'.'|',';
WS : (' ' | '\t' |'\n' |'\r' )+ ;

我只是不明白为什么它的“day”读得很好,但它确实拒绝了其他人?我确实像你写的那样尝试过,但它仍然与年份不匹配问题不在于我们写的东西的逻辑,因为它接受第一个,但仍然拒绝其他,即使我尝试过你,我就是不明白为什么它读“day”完全是这样,但它确实拒绝了其他人?我确实在你写的时候尝试过,但它仍然与我们所写的逻辑不符,因为它接受第一个,但仍然拒绝其他人,即使我尝试你编辑过的版本