首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ANTLR上重写树时,抛出java.lang.NullPointerException

在ANTLR上重写树时,抛出java.lang.NullPointerException
EN

Stack Overflow用户
提问于 2012-06-01 20:10:13
回答 1查看 261关注 0票数 1

我正在尝试为QuickBasic创建一个解析器,这是我获取注释的尝试:

代码语言:javascript
复制
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';

即使我只使用token注释重写,而不使用其他注释,我仍然会得到相同的错误。

代码语言:javascript
复制
// It DOESN'T WORK EITHER
Comment
    :    (R E M | Quote) ~('\n')* -> ^(COMMENT)
    ;

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

代码语言:javascript
复制
// THIS WORKS
Comment
    :    (R E M | Quote) ~('\n')*
    ;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-01 20:26:44

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

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

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

代码语言:javascript
复制
Comment
    :    R E M ~('\r' | '\n')* { Skip(); }
    |    Quote ~('\r' | '\n')* { Skip(); }
    ;

或者更简洁:

代码语言:javascript
复制
Comment
    :    (Quote | R E M) ~('\r' | '\n')* { Skip(); }
    ;

然而,如果你真的热衷于将Comment标记留在流中,并去掉"rem"或评论中的引用,那么可以这样做:

代码语言:javascript
复制
Comment
    :    (Quote | R E M) t=NonLineBreaks { Text = $t.text; }
    ;

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

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

代码语言:javascript
复制
comment
    :    Comment -> ^(COMMENT Comment)
    ;
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10850007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档