ANTLR生成空条件

时间:2011-06-29 19:27:54

标签: java antlr grammar antlr3

我正在尝试学习使用ANTLR,但在这种情况下我无法弄清楚我的代码有什么问题。我希望对于有经验的人来说,这将非常容易。这是语法(非常简短)。

grammar SmallTest;

@header {
package parseTest;
import java.util.ArrayList;
}

prog returns [ArrayList<ArrayList<String>> all]
    :(stat { if ($all == null)
               $all = new ArrayList<ArrayList<String>>();
             $all.add($stat.res);
           } )+
    ;

stat returns [ArrayList<String> res]
    :(element  { if ($res == null)
                   $res = new ArrayList<String>();
                 $res.add($element.text);
               } )+ NEWLINE
    |   NEWLINE
    ;

element: ('a'..'z'|'A'..'Z')+ ;
NEWLINE:'\r'? '\n' ;

问题在于,当我生成Java代码时,有一些空的if条件,并且编译器因此显示错误,我可以手动编辑,但这可能会更糟。我猜这里有些不对劲。

很抱歉,这一定是非常愚蠢的,但我的例子与网站上的例子非常相似,我无法想象这样可以将差异化为差异。

非常感谢。

2 个答案:

答案 0 :(得分:4)

您应该将列表的初始化放在规则的@init { ... }块中,然后在规则中的任何内容匹配之前执行。

此外,您的element规则不应该是解析器规则,而应该是词法分析器规则(它应该以大写字母开头!)。

您的解析器的入口点prog规则应该以{{1​​}}令牌结束,否则解析器可能会在所有令牌被正确处理之前停止。

最后,EOF部分仅适用于解析器(它是@header { ... }的简写),您还需要将包声明添加到词法分析器。

工作演示:

SmallTest.g

@parser::header { ... }

Main.java

grammar SmallTest;

@header {
package parseTest;
import java.util.ArrayList;
}

@lexer::header {
package parseTest;
}

prog returns [ArrayList<ArrayList<String>> all]
@init {$all = new ArrayList<ArrayList<String>>();}
  :  (stat {$all.add($stat.res);})+ EOF
  ;

stat returns [ArrayList<String> res]
@init {$res = new ArrayList<String>();}
  :  (ELEMENT {$res.add($ELEMENT.text);})* NEWLINE
  ;

ELEMENT : ('a'..'z'|'A'..'Z')+ ;
NEWLINE : '\r'? '\n' ;
SPACE   : ' ' {skip();};

要全部运行,请执行:

java -cp antlr-3.3.jar org.antlr.Tool parseTest/SmallTest.g 
javac -cp .:antlr-3.3.jar parseTest/*.java
java -cp .:antlr-3.3.jar parseTest.Main

产生:

[[a, bb, ccc], [dddd, eeeee]]

答案 1 :(得分:0)

尝试将element转换为令牌

ELEMENT: ('a'..'z'|'A'..'Z')+ ;