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

查看:21
本文介绍了在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')*
    ;

推荐答案

重写规则仅适用于解析器规则,不适用于词法分析器规则.而 t=~('\n')* 将只导致最后一个非换行符被存储在 t-label 中,所以不会有无论如何工作.

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天全站免登陆