antl3:测试解析器时的Java堆空间

时间:2013-01-28 15:25:09

标签: antlr3

我正在尝试构建一个简单的配置文件阅读器来读取这种格式的文件:

A .-
B -...
C -.-.
D -..
E .

这是我到目前为止的语法:

grammar def;

@header {
    package mypackage.parser;
}
@lexer::header { package mypackage.parser; }
file
    :   line+;

line    :   ID WS* CODE NEWLINE;

ID  :   ('A'..'Z')*
    ;

CODE    :   ('-'|'.')*;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

WS  :   ( ' '
        | '\t'
        ) {$channel=HIDDEN;}
    ;
NEWLINE:'\r'? '\n' ;

这是我的试验台(junit4)

@Test
public void BasicGrammarCheckGood() {
       String CorrectlyFormedLine="A .-;\n";
       ANTLRStringStream input;
        defLexer lexer;
        defParser parser;

         input = new ANTLRStringStream(CorrectlyFormedLine);
        lexer = new defLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
         parser = new defParser(tokens);
         try {
        parser.line();
         }
         catch(RecognitionException re) { fail(re.getMessage()); } 
   }

如果我使用更正的格式化字符串运行此测试 - 代码退出时没有任何异常或输出。

但是,如果为解析器提供如下无效字符串:“xA .-; \ n”,则代码会旋转一段时间,然后以“Java堆空间”退出。

(如果我使用顶级规则'file'开始我的测试,那么我得到相同的结果 - 附加(重复)输出“第1行:0不匹配的输入''期待CODE”)

这里出了什么问题?我似乎从来没有得到无效输出的“RecognitionException”?

编辑:这是我的语法文件(Fragment),在这里提供建议之后 - 这避免了'Java堆空间'问题。

file
    :   line+ EOF;

line    :   ID WS* CODE NEWLINE;

ID  :   ('A'..'Z')('A'..'Z')*
    ;

CODE    :   ('-'|'.')('-'|'.')*;

1 个答案:

答案 0 :(得分:0)

您的某些词法规则匹配零个字符(空字符串):

ID  :   ('A'..'Z')*
    ;

CODE    :   ('-'|'.')*;

当然,输入中有无限量的空字符串,导致词法分析器继续生成标记,一段时间后会导致堆空间错误。

始终让词法分析器规则至少匹配1个字符。

修改

两个(小)评论:

  1. 由于您将WS令牌放在隐藏的频道上,因此您无需在解析器规则中添加它们。因此line变为line : ID CODE NEWLINE;
  2. ('A'..'Z')('A'..'Z')*之类的内容可以这样写:('A'..'Z')+