语句匹配后需要换行符或EOF

时间:2017-07-26 03:12:00

标签: parsing antlr4 semantics

只是寻找一种简单的方法来让ANTLR4生成一个解析器,它将执行以下操作(在<{strong> ;之后忽略任何):

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 Parse Tree似乎给了我输入错误,例如:

.

(假装点不在那里,字面上没有输入)

int #i int #j

Woops,我们在同一条线上有两个!

关于如何实现这一目标的任何想法?我很感激帮助。

1 个答案:

答案 0 :(得分:1)

我已经简化了你的语法,但是在每个语句正确解析后需要一个行尾序列。

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以减少重复:

语法测试;

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;