我正在尝试编写一个语法来解析单行注释。以“--”开头的注释可以出现在文件中的任何位置。
我的基本语法如下所示。
语法(aa.g4):
grammar aa;
statement
: commentStatement* ifStatement
| commentStatement* returnStatement
;
ifStatement
: 'if' '(' expression ')'
returnStatement+
;
returnStatement : 'return' expression ';' ;
commentStatement : '--' (.+?) '\\n'? ;
expression : IDENTIFIER ;
IDENTIFIER : [a-z]([A-Za-z0-9\-\_])* ;
NEWLINE : '\r'? '\n' -> skip ;
WS : [ \t\r\f\n]+ -> skip ;
测试类:
public class aaTest {
static class aaListener extends aaBaseListener {
public void enterCommentStatement(CommentStatementContext ctx) {
System.out.println(ctx.getText());
}
}
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream("aa.txt");
CharStream stream = new ANTLRInputStream(is);
aaLexer lexer = new aaLexer(stream);
TokenStream tokenStream = new CommonTokenStream(lexer);
aaParser parser = new aaParser(tokenStream);
ParseTree aParseTree = parser.statement();
ParseTreeWalker aWalker = new ParseTreeWalker();
aWalker.walk(new aaListener(), aParseTree);;
}
}
输入:
--comment1
-- if comment
if (x) --mid if comment
--end comment
return result;
输出:
--comment1a
--ifcommentif(x) <<< error output
--midifcomment
--endcomment
查询:
- 上面解析错误输出有什么问题。我只需要“--如果 评论”打印。
- 如何获取并输出带空格的实际评论。
最佳答案
首先,您应该按照您真正的意思定义行注释规则。非贪婪运算符没有按照您预期的方式执行。
LineComment
: '--' ~[\r\n]* -> channel(HIDDEN)
;
其次,如果您希望 token 流包含有关空格和换行符的信息,您应该将它们移动到隐藏 channel ,而不是使用 skip
命令。 skip
命令完全删除标记,使其看起来好像文本根本不存在于输入中。
NEWLINE
: '\r'? '\n' -> channel(HIDDEN)
;
WS
: [ \t\f]+ -> channel(HIDDEN)
;
注释不会出现在解析树中,并且您不会在任何解析器规则中使用 LineComment
。要获取解析树中另一个标记之前或之后的这些标记的信息,您可以直接检查特定索引周围的标记(使用 TokenStream.get(int)
)或使用实用程序方法,例如 BufferedTokenStream.getHiddenTokensToRight
或BufferedTokenStream.getHiddenTokensToLeft
.
关于antlr4 - 解析单行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23976617/