解析单行注释

Pra*_*rma 2 antlr4

我正在尝试编写用于解析单行注释的语法.以" - "开头的注释可以出现在文件的任何位置.

我的基本语法如下所示.

语法(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 ;
Run Code Online (Sandbox Code Playgroud)

测试类:

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);;
    }
}
Run Code Online (Sandbox Code Playgroud)

输入:

--comment1
-- if comment
if (x) --mid if comment
  --end comment
return result;
Run Code Online (Sandbox Code Playgroud)

输出:

--comment1a
--ifcommentif(x)     <<< error output
--midifcomment
--endcomment
Run Code Online (Sandbox Code Playgroud)

查询:

  1. 解析上面的错误输出有什么问题.我只需要打印" - 如果评论".
  2. 如何获取并输出带空格的实际注释.

Sam*_*ell 8

首先,您应该定义您的行注释规则,因为您真正的意思是它.非贪婪的运算符没有按照您的意图执行.

LineComment
  : '--' ~[\r\n]* -> channel(HIDDEN)
  ;
Run Code Online (Sandbox Code Playgroud)

其次,如果您希望令牌流包含有关空格和换行符的信息,则应将它们移动到隐藏通道而不是使用该skip命令.该skip命令完全删除了令牌,使得它看起来好像文本根本不在输入中.

NEWLINE
  : '\r'? '\n' -> channel(HIDDEN)
  ;

WS
  : [ \t\f]+ -> channel(HIDDEN)
  ;
Run Code Online (Sandbox Code Playgroud)

注释不会出现在解析树中,也不会LineComment在任何解析器规则中使用.若要获取有关之前或之后解析树另一个标记这些标记的信息,您可以检查直接左右(使用特定索引令牌TokenStream.get(int))或类似工具方法BufferedTokenStream.getHiddenTokensToRightBufferedTokenStream.getHiddenTokensToLeft.