2012-10-22 46 views
1

我正在使用ANTLR 3.x创建一个解析器,该解析器以Java为目标。我编写了解析器语法(用于创建抽象语法树AST)和树语法(用于在AST上执行操作)。最后,为了测试这两个语法文件,我用Java编写了一个测试文件。ANTLR 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 i.e, 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 i.e, from protocol.tokens file 
    
  2. 在在protocolWalker,我可以创建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的对象不能被创建。我在例子和教程中看到这样的对象被创建。

+0

我已阅读该书The definitive antlr reference,构建领域特定语言,并且也遵循了一些在线教程。 –

回答

1

在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的树分析器。

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

+0

而不是评论,我在下面的答案中回答了你 –

0

谢谢你的回复,那是一个愚蠢的错误。 Token问题和protocolWalker的创建对象现在已经解决了,但是每当我改变语法,protocol.g或protocolWalker.g,我都必须在protocolParser.java和protocolWalker.java中再次编写包名称(每次)。之前我和lexer文件有同样的问题,但是下面的声明解决了这个问题。

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

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

另外,我用SWING开发了一个使用SWING的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没有显示在输出中?

任何想法/帮助?

再次感谢您。

+0

使用以下链接解决了解析器包问题 [为什么我的头文件不会出现在词法分析器和解析器中?](http:// www。 antlr.org/wiki/pages/viewpage.action?pageId=819257) @tenterhook –

+1

** Swing **:听起来你只需要一个简单的Swing应用程序就可以了。看看那里的一些教程,如果你陷入困境,发布一个新问题(我不是一个Swing的人,所以我不会有太大的帮助)。 **输出**:在更新并重新生成protocolWalker.g之后,我运行了主系统并获得了正确的输出。如果重新生成代码不能解决您的问题,请考虑为它写一个新问题。 – user1201210

+0

非常感谢。 –