2011-07-20 7 views
0

それはここで私の最初の質問:)私は、単純な文法のためにANTLRとの異種ASTを構築したいと思いますANTLR:異機種混在ASTと虚数トークン

です。 ASTノードを表すための異なるインタフェースが存在する。 g。 IInfiExp、IVariableDecl。 ANTLRは、CommonTreeを使ってソースコードのすべての情報(行番号、文字位置など)を保持しています。これをASTインターフェイスIInfixExpの実装のベースとして使用したいと考えています...

ノードタイプとしてCommonTreeと出力としてASTを取得し、私が設定:

options { 
    language  = Java; 
    k   = 1; 
    output  = AST; 
    ASTLabelType = CommonTree; 
} 

IInifxExpは次のとおりです。

package toylanguage; 

public interface IInfixExp extends IExpression { 
    public enum Operator { 
     PLUS, MINUS, TIMES, DIVIDE; 
    } 

    public Operator getOperator(); 

    public IExpression getLeftHandSide(); 

    public IExpression getRightHandSide(); 
} 

と実装InfixExpです:

これはPLUS becouse、正常に動作します

exp // e.g. a+b 
    : term ((PLUS<InfixExp>^|MINUS<InfixExp>^) term)* 
    ; 

term // e.g. a*b 
    : atom ((TIMES<InfixExp>^|DIVIDE<InfixExp>^) atom)* 
    ; 

、MINUSなど "本物" のトークンです:の

対応するルールがあります。今

しかし、架空のトークンに来る:

tokens { 
    PROGRAM; 
} 

対応するルールがある:これにより

program // e.g. var a, b; a + b 
    : varDecl* exp 
    -> ^(PROGRAM<Program> varDecl* exp) 
    ; 

、ANTLRは、ルートノードとしてPROGRAMでツリーを作成しません。 InfixExpないプログラム(トークン)コンストラクタが、プログラム(INT)とは異なり

root_1 = (CommonTree)adaptor.becomeRoot(new Program(PROGRAM), root_1); 

呼び出される:パーサーで

は、次のコードは、プログラムのインスタンスを作成します。

プログラムは次のとおりです。トークンなしスーパー()CommonTreeイストのビルドで、それの結果として

public Program(int tokeType) { 
     // What to do? 
     super(); 
    } 

package toylanguage; 

import java.util.Collections; 
import java.util.LinkedList; 
import java.util.List; 

import org.antlr.runtime.Token; 
import org.antlr.runtime.tree.CommonTree; 

class Program extends CommonTree implements IProgram, IInitializable { 
    private final LinkedList<IVariableDecl> variableDeclarations = new LinkedList<IVariableDecl>(); 
    private IExpression expression = null; 

    Program(Token token) { 
     super(token); 
    } 

    public Program(int tokeType) { 
     // What to do? 
     super(); 
    } 

    @Override 
    public List<IVariableDecl> getVariableDeclarations() { 
     // don't allow to change the list 
     return Collections.unmodifiableList(variableDeclarations); 
    } 

    @Override 
    public IExpression getExpression() { 
     return expression; 
    } 

    @Override 
    public void initialize() { 
     // program: varDecl* exp; 

     // at least one child 
     assert getChildCount() > 0; 

     // the last one is a IExpression 
     assert getChild(getChildCount() - 1) instanceof IExpression; 

     // iterate over varDecl* 
     int i = 0; 
     while (getChild(i) instanceof IVariableDecl) { 
      variableDeclarations.add((IVariableDecl) getChild(i)); 
      i++; 
     } 

     // exp 
     expression = (IExpression) getChild(i); 
    } 
} 

あなたはコンストラクタを見ることができます。したがって、CommonTreeAdaptor.rulePostProcessingはルートとしてのトークンを持つツリーではなくフラットなリストを参照します。

マイTreeAdaptorは、次のようになります。

package toylanguage; 

import org.antlr.runtime.tree.CommonTreeAdaptor; 

public class ToyTreeAdaptor extends CommonTreeAdaptor { 
    public Object rulePostProcessing(Object root) { 
     Object result = super.rulePostProcessing(root); 

     // check if needs initialising 
     if (result instanceof IInitializable) { 
      IInitializable initializable = (IInitializable) result; 
      initializable.initialize(); 
     } 

     return result; 
    }; 
} 

そして、私が使うものをテストするために:完全性については

package toylanguage; 

import org.antlr.runtime.ANTLRStringStream; 
import org.antlr.runtime.CommonTokenStream; 
import org.antlr.runtime.RecognitionException; 
import org.antlr.runtime.TokenStream; 
import org.antlr.runtime.tree.CommonTree; 

import toylanguage.ToyLanguageParser.program_return; 

public class Processor { 
    public static void main(String[] args) { 
     String input = "var a, b; a + b + 123"; // sample input 

     ANTLRStringStream stream = new ANTLRStringStream(input); 
     ToyLanguageLexer lexer = new ToyLanguageLexer(stream); 
     TokenStream tokens = new CommonTokenStream(lexer); 
     ToyLanguageParser parser = new ToyLanguageParser(tokens); 
     ToyTreeAdaptor treeAdaptor = new ToyTreeAdaptor(); 
     parser.setTreeAdaptor(treeAdaptor); 

     try { 
      // test with: var a, b; a + b 
      program_return program = parser.program(); 

      CommonTree root = program.tree; 
      // prints 'a b (+ a b)' 
      System.out.println(root.toStringTree()); 

      // get (+ a b), the third child of root 
      CommonTree third = (CommonTree) root.getChild(2); 

      // prints '(+ a b)' 
      System.out.println(third.toStringTree()); 

      // prints 'true' 
      System.out.println(third instanceof IInfixExp); 

      // prints 'false' 
      System.out.println(root instanceof IProgram); 
     } catch (RecognitionException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

を、ここでは完全な文法は次のとおりです。

grammar ToyLanguage; 

options { 
    language  = Java; 
    k   = 1; 
    output  = AST; 
    ASTLabelType = CommonTree; 
} 

tokens { 
    PROGRAM; 
} 

@header { 
    package toylanguage; 
} 

@lexer::header { 
    package toylanguage; 
} 

program // e.g. var a, b; a + b 
    : varDecl* exp 
    -> ^(PROGRAM<Program> varDecl* exp) 
    ; 

varDecl // e.g. var a, b; 
    : 'var'! ID<VariableDecl> (','! ID<VariableDecl>)* ';'! 
    ; 

exp // e.g. a+b 
    : term ((PLUS<InfixExp>^|MINUS<InfixExp>^) term)* 
    ; 

term // e.g. a*b 
    : atom ((TIMES<InfixExp>^|DIVIDE<InfixExp>^) atom)* 
    ; 

atom 
    : INT<IntegerLiteralExp> // e.g. 123 
    | ID<VariableExp>  // e.g. a 
    | '(' exp ')' -> exp  // e.g. (a+b) 
    ; 

INT : ('0'..'9')+ ; 
ID  : ('a'..'z')+ ; 
PLUS : '+' ; 
MINUS : '-' ; 
TIMES : '*' ; 
DIVIDE : '/' ; 

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

OK、最終質問はどうするのですか

program // e.g. var a, b; a + b 
    : varDecl* exp 
    -> ^(PROGRAM<Program> varDecl* exp) 
    ; 

ルートとしてPROGRAMを持つツリー

^(PROGRAM varDecl* exp) 

及びません(この数多くのコードフラグメントのため申し訳ありませんが)

(varDecl* exp) ? 

チャオ頂点

答えて

1

てみ付きフラットリスト次のコンストラクタを作成します。

public Program(int tokenType) { 
    super(new CommonToken(tokenType, "PROGRAM")); 
} 
+0

これはうまくいく:)ありがとう! – Vertex

+0

@Vertex、聞いてよかったです。どういたしまして。 –

関連する問題