ANTLR 生成空条件

发布于 2024-11-17 22:03:24 字数 837 浏览 5 评论 0原文

我正在尝试学习使用 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 条件,并且编译器因此显示错误,我可以手动编辑它,但这可能会更糟。我想这里面有什么问题。

抱歉问这个问题,这真的很愚蠢,但我的例子与网站上的例子非常相似,我无法想象有什么方法可以再原子化差异。

非常感谢。

I'm trying to learn to use ANTLR, but I cannot figure out what's wrong with my code in this case. I hope this will be really easy for anyone with some experience with it. This is the grammar (really short).

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' ;

The problem is that when I generate the Java code there are some empty if conditions, and the compiler displays an error because of that, I could edit that manually, but that would probably be much worse. I guess something is wrong in this.

Sorry for asking, this has to be really stupid, but my example is so similar to those in the site that I cannot imagine a way to atomize the differences any more.

Thank you very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

秋意浓 2024-11-24 22:03:24

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

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

解析器的入口点,prog 规则,应该以 EOF 标记结束,否则解析器可能会在所有标记得到正确处理之前停止。

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

一个有效的演示:

SmallTest.g

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();};

Main.java

package parseTest;

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    SmallTestLexer lexer = new SmallTestLexer(new ANTLRStringStream("a bb ccc\ndddd eeeee\n"));
    SmallTestParser parser = new SmallTestParser(new CommonTokenStream(lexer));
    System.out.println(parser.prog());
  }
}

要运行它,请执行以下操作:

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]]

You should put the initialization of your lists inside the @init { ... } block of the rules, which get executed before anything in the rule is matched.

Also, your element rule should not be a parser rule, but a lexer rule instead (it should start with a capital!).

And the entry point of your parser, the prog rule, should end with the EOF token otherwise the parser might stop before all tokens are handled properly.

Finally, the @header { ... } section only applies to the parser (it is a short-hand for @parser::header { ... }), you need to add the package declaration to the lexer as well.

A working demo:

SmallTest.g

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();};

Main.java

package parseTest;

import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    SmallTestLexer lexer = new SmallTestLexer(new ANTLRStringStream("a bb ccc\ndddd eeeee\n"));
    SmallTestParser parser = new SmallTestParser(new CommonTokenStream(lexer));
    System.out.println(parser.prog());
  }
}

And to run it all, do:

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

which yields:

[[a, bb, ccc], [dddd, eeeee]]
青春如此纠结 2024-11-24 22:03:24

尝试将 element 转换为令牌

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

Try converting element into a token

ELEMENT: ('a'..'z'|'A'..'Z')+ ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文