需要换行或EOF声明赛后
问题描述:
就找得到ANTLR4生成一个解析器,将做如下的简单方法(忽略任何后;
):需要换行或EOF声明赛后
int #i ; defines an int
int #j ; see how I have to go to another line for another statement?
我解析器是作为以下:
compilationUnit:
(statement END?)*
statement END?
EOF
;
statement:
intdef |
WS
;
// 10 - 1F block.
intdef:
'intdef' Identifier
;
// Lexer.
Identifier: '#' Letter LetterOrDigit*;
fragment Letter: [a-zA-Z_];
fragment LetterOrDigit: [a-zA-Z0-9$_];
// Whitespace, fragments and terminals.
WS: [ \t\r\n\u000C]+ -> skip;
//COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
END: (';' ~[\r\n]*) | '\n';
从本质上说,任何时候,我有一个statement
,我需要它的另一个输入之前,需要一个换行符。我不在乎是否有3条新线,然后在第二条线上存在一组标签,只要有新线。
的问题是,在ANTLR4解析树似乎是给我的错误的输入,如:
.
(假装点心不是在那里,它的字面意思无输入)
int #i int #j
Woops ,我们在同一行上有两个!
关于我如何实现这一点的任何想法?我很感激帮助。
答
我已经简化了一下你的语法,但是在每个语句正确解析之后,它都要求结束行序列。
grammar Testnl;
program: (statement)* EOF ;
statement: 'int' Identifier EOL;
Identifier: '#' Letter LetterOrDigit*;
fragment Letter: [a-zA-Z_];
fragment LetterOrDigit: [a-zA-Z0-9$_];
EOL: ';' .*? '\r\n'
| ';' .*? '\n'
;
WS: [ \t\r\n\u000C]+ -> skip;
它解析
int #i ;
int #j;
[@0,0:2='int',<'int'>,1:0]
[@1,4:5='#i',<Identifier>,1:4]
[@2,7:9=';\r\n',<EOL>,1:7]
[@3,10:12='int',<'int'>,2:0]
[@4,14:15='#j',<Identifier>,2:4]
[@5,16:18=';\r\n',<EOL>,2:6]
[@6,19:18='<EOF>',<EOF>,3:0]
它还忽略的东西分号后为刚刚EOL令牌的一部分:
[@0,0:2='int',<'int'>,1:0]
[@1,4:5='#i',<Identifier>,1:4]
[@2,7:20='; ignore this\n',<EOL>,1:7]
[@3,21:23='int',<'int'>,2:0]
[@4,25:26='#j',<Identifier>,2:4]
[@5,27:28=';\n',<EOL>,2:6]
[@6,29:28='<EOF>',<EOF>,3:0]
使用或者换行或回车符,换行符就好了。那是你在找什么?
编辑
每OP评论,做了小改动,让连续EOL标记,并且也动EOL令牌statement
,以减少重复:
语法Testnl;
program: (statement EOL)* EOF ;
statement: 'int' Identifier;
Identifier: '#' Letter LetterOrDigit*;
fragment Letter: [a-zA-Z_];
fragment LetterOrDigit: [a-zA-Z0-9$_];
EOL: ';' .*? ('\r\n')+
| ';' .*? ('\n')+
;
WS: [ \t\r\n\u000C]+ -> skip;
感谢您的回答!那就是我正在寻找的。 – finnrayment
其实,快速的问题,有没有办法让我在语句之间和最后一个语句之后有新行?目前,他们必须一个接一个地插入,不要有任何杂散的新线。 – finnrayment
@finnrayment当然,做完了,看上面的编辑语法。干杯! – TomServo