在ANTLR上重写树时,抛出java.lang.NullPointerException [英] When rewriting tree on ANTLR, java.lang.NullPointerException is thrown
问题描述
我正在尝试为 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屋!