ANTLR java测试文件无法创建树语法对象

我正在使用针对java的ANTLR 3.x创建一个解析器。 我编写了解析器语法(用于创建抽象语法树,AST)和树语法(用于在AST上执行操作)。 最后,为了测试两个语法文件,我用Java编写了一个测试文件。

看看下面的代码,

协议语法

grammar protocol; options { language = Java; output = AST; } tokens{ //imaginary tokens PROT; INITIALP; PROC; TRANSITIONS; } @header { import twoprocess.Configuration; package com.javadude.antlr3.x.tutorial; } @lexer::header { package com.javadude.antlr3.x.tutorial; } /* parser rules, in lowercase letters */ program : declaration+ ; declaration :protocol |initialprocess |process |transitions ; protocol :'protocol' ID ';' -> ^(PROT ID) ; initialprocess :'pin' '=' INT ';' -> ^(INITIALP INT) ; process :'p' '=' INT ';' -> ^(PROC INT) ; transitions :'transitions' '=' INT ('(' INT ',' INT ')') + ';' -> ^(TRANSITIONS INT INT INT*) ; /* lexer rules (tokens), in upper case letters */ ID : (('a'..'z' | 'A'..'Z'|'_')('a'..'z' | 'A'..'Z'|'0'..'9'|'_'))*; INT : ('0'..'9')+; WHITESPACE : ('\t' | ' ' | '\r' | '\n' | '\u000C')+ {$channel = HIDDEN;}; 

protocolWalker

 grammar protocolWalker; options { language = Java; //Error, eclipse can't access tokenVocab named protocol tokenVocab = protocol; //import tokens from protocol.g ie, from protocol.tokens file ASTLabelType = CommonTree; } @header { import twoprocess.Configuration; package com.javadude.antlr3.x.tutorial; } program : declaration+ ; declaration :protocol |initialprocess |process |transitions ; protocol :^(PROT ID) {System.out.println("create protocol " +$ID.text);} ; initialprocess :^(INITIALP INT) {System.out.println("");} ; process :^(PROC INT) {System.out.println("");} ; transitions :^(TRANSITIONS INT INT INT*) {System.out.println("");} ; 

Protocoltest.java

 package com.javadude.antlr3.x.tutorial; import org.antlr.runtime.*; import org.antlr.runtime.tree.*; import org.antlr.runtime.tree.CommonTree; import org.antlr.runtime.tree.CommonTreeNodeStream; public class Protocoltest { /** * @param args */ public static void main(String[] args) throws Exception { //create input stream from standard input ANTLRInputStream input = new ANTLRInputStream(System.in); //create a lexer attached to that input stream protocolLexer lexer = new protocolLexer(input); //create a stream of tokens pulled from the lexer CommonTokenStream tokens = new CommonTokenStream(lexer); //create a pareser attached to teh token stream protocolParser parser = new protocolParser(tokens); //invoke the program rule in get return value protocolParser.program_return r =parser.program(); CommonTree t = (CommonTree)r.getTree(); //output the extracted tree to the console System.out.println(t.toStringTree()); //walk resulting tree; create treenode stream first CommonTreeNodeStream nodes = new CommonTreeNodeStream(t); //AST nodes have payloads that point into token stream nodes.setTokenStream(tokens); //create a tree walker attached to the nodes stream //Error, can't create TreeGrammar object called walker protocolWalker walker = new protocolWalker(nodes); //invoke the start symbol, rule program walker.program(); } } 

问题:

  1. 在protocolWalker中,我无法访问令牌(protocol.tokens)

     //Error, eclipse can't access tokenVocab named protocol tokenVocab = protocol; //import tokens from protocol.g ie, from protocol.tokens file 
  2. 在In protocolWalker中,我可以在动作列表中创建名为Configuration的java类对象吗?

     protocol :^(PROT ID) {System.out.println("create protocol " +$ID.text); Configuration conf = new Configuration(); } ; 
  3. 在Protocoltest.java中

     //create a tree walker attached to the nodes stream //Error, can't create TreeGrammar object called walker protocolWalker walker = new protocolWalker(nodes); 

    无法创建protocolWalker的对象。 我在示例和教程中已经看到创建了这样的对象。

在protocolWalker中,我无法访问令牌(protocol.tokens)……

它似乎正在访问protocol.tokens罚款:将tokenVocab更改为其他东西会产生一个它现在不会产生的错误。 protocolWalker.g的问题在于它被定义为令牌解析器( grammar protocolWalker ),但它被用作树解析器。 将语法定义为tree grammar protocolWalker消除了我所看到的关于未定义标记的错误。

在protocolWalker中,我可以在动作列表中创建名为Configuration的java类对象吗?

是的你可以。 正常的Java编程警告适用于导入类等等,但它可以像System.out.println这样的代码使用。

在Protocoltest.java中…无法创建protocolWalker的对象。

protocolWalker.g(现在)生成一个名为protocolWalkerParser的令牌解析器。 当您将其更改为树语法时,它将生成一个名为protocolWalker的树解析器。

非常感谢发布整个语法。 这使得回答问题变得更加容易。

谢谢你的回复,这是一个愚蠢的错误。 现在已经解决了令牌问题和protocolWalker的创建对象,但每当我更改语法时,无论是protocol.g还是protocolWalker.g,我都必须在protocolParser.java和protocolWalker.java中再次(每次)写入包名。 我之前遇到过与lexer文件相同的问题,但是以下声明已经克服了这个问题。

 @header { package com.javadude.antlr3.x.tutorial; } 

但我不知道如何克服这个问题?

另外,我使用SWING在Java中开发了一个GUI,我有一个textarea。 在该文本区域中,用户将写入输入,就像我的语法用户会写的那样,

 protocol test; pin = 5; p = 3; transitions = 2(5,0) (5,1); 

如何在Java Swing GUI中处理此输入并在那里生成输出?

此外,如果我将protocolWalker.g的以下部分提供给

 protocol :^(PROT ID) { System.out.println("create protocol " +$ID.text); Configuration conf = new Configuration(); conf.showConfiguration(); } ; initialprocess :^(INITIALP INT) {System.out.println("create initial process (with state) ");} ; process :^(PROC INT) {System.out.println("create processes ");} ; 

并使用以下输入运行测试文件,

 protocol test; pin = 5; p = 3; transitions = 2(5,0) (5,1); 

我得到以下输出

 (PROT test) (INITIALP 5) (PROC 3) (TRANSITIONS 2 5 0 5 1) create protocol test 

为什么protocolWalker.g中的第二个和第三个println没有显示在输出中?

有什么想法/帮助吗?

再一次谢谢你。