在ANTLR上重写树时,抛出java.lang.NullPointerException [英] When rewriting tree on ANTLR, java.lang.NullPointerException is thrown

查看:113
本文介绍了在ANTLR上重写树时,抛出java.lang.NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为QuickBasic创建一个解析器,这是我尝试获取评论的方法:

I'm trying to create a parser for QuickBasic and this is my attempt to get the comments:

grammar QuickBasic;

options 
{
    language = 'CSharp2';
    output = AST;
}

tokens
{
    COMMENT;
}

parse
    :    .* EOF
    ;

// DOESN'T WORK
Comment
    :    R E M t=~('\n')* { Text = $t; } -> ^(COMMENT $t)
    |    Quote t=~('\n')* { Text = $t; } -> ^(COMMENT $t)
    ;

Space  
    :    (' ' | '\t' | '\r' | '\n' | '\u000C') { Skip(); }  
    ;

fragment Quote : '\'';    
fragment E     : 'E' | 'e';
fragment M     : 'M' | 'm';
fragment R     : 'R' | 'r';

即使我仅使用令牌COMMENT进行重写,仅此而已,我仍然遇到相同的错误.

Even if I rewrite using only the token COMMENT and nothing more, I still get the same error.

// It DOESN'T WORK EITHER
Comment
    :    (R E M | Quote) ~('\n')* -> ^(COMMENT)
    ;

如果我放弃重写,它会起作用:

If I give up rewriting, it works:

// THIS WORKS
Comment
    :    (R E M | Quote) ~('\n')*
    ;

推荐答案

重写规则仅适用于解析器规则,不适用于lexer规则.并且t=~('\n')*将仅将最后一个非换行符存储在t-标签中,因此无论如何都不会起作用.

Rewrite rules only work with parser rules not with lexer rules. And t=~('\n')* will cause only the last non-line-break to be stored in the t-label, so that wouldn't have worked anyway.

但是为什么不一起跳过这些Comment标记呢?如果将它们留在令牌流中,则需要在所有解析器规则中考虑Comment令牌(其中Comment令牌有效地出现):不是您想要的,对吗?

But why not skip these Comment tokens all together. If you leave them in the token stream, you'd need to account for Comment tokens in all your parser rules (where Comment tokens are valid to occur): not something you'd want, right?

要跳过该规则,只需在规则末尾调用Skip():

To skip the, simply call Skip() at the end of the rule:

Comment
    :    R E M ~('\r' | '\n')* { Skip(); }
    |    Quote ~('\r' | '\n')* { Skip(); }
    ;

或更简洁:

Comment
    :    (Quote | R E M) ~('\r' | '\n')* { Skip(); }
    ;

但是,如果您真的很想将Comment令牌留在流中并删除"rem"或注释中的引号,请按照以下步骤进行操作:

However, if you're really keen on leaving Comment tokens in the stream and strip either "rem" or the quote from the comment, do it like this:

Comment
    :    (Quote | R E M) t=NonLineBreaks { Text = $t.text; }
    ;

fragment NonLineBreaks : ~('\r' | '\n')+;

然后,您还可以创建一个解析器规则,该规则创建一个以COMMENT为根的AST(尽管我看不到简单使用Comment的好处):

You could then also create a parser rule that creates an AST with COMMENT as the root (although I don't see the benefit over simply using Comment):

comment
    :    Comment -> ^(COMMENT Comment)
    ;

这篇关于在ANTLR上重写树时,抛出java.lang.NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆