Расширить ANTLR3 AST - PullRequest
       42

Расширить ANTLR3 AST

3 голосов
/ 03 октября 2011

С помощью ANTLR2 вы можете определить что-то вроде этого в файле определения грамматики:

options
{
   language = "CSharp";
   namespace = "Extended.Tokens";
}

tokens {
   TOKEN<AST=Extended.Tokens.TokenNode>;
}

И затем вы можете создать класс:

public class TokenNode: antlr.BaseAST
{
    ...
}

Любая идея, если что-то вроде этогоможно использовать (делегировать создание класса фабрике AST вместо того, чтобы я делал репликацию дерева вручную)?Это не работает просто путем простого определения грамматики из старого в новый формат, и я попытался найти что-то похожее на их сайте и в примерах.Есть подсказки?

РЕДАКТИРОВАТЬ

Я не пытаюсь создавать пользовательские токены, а пользовательские "анализаторы узлов".

Чтобы «выполнить» дерево, у вас есть 2 варианта (насколько я понял):

  1. создать «посетителя дерева» и обработать значения, или
  2. создать синтаксический анализатор дерева, «почти дублируя» определение грамматики.

В случае v2 я мог бы украсить узел дерева до любого понравившегося мне метода, а затем вызвать их после запуска анализатора, просто вызвав что-то вроде 'execute' из корневого узла.

1 Ответ

4 голосов
/ 03 октября 2011

Я немного знаю C #, но не должно быть большой разницы с целью Java.

Вы можете создать - и позволить ANTLR использовать - собственное дерево, установив ASTLabelType в options { ... }section (в данном случае XTree):

Tg

grammar T;

options {
  output=AST;
  ASTLabelType=XTree;
}

tokens {
  ROOT;
}

@parser::header {
  package demo;
  import demo.*;
}

@lexer::header {
  package demo;
  import demo.*;
}

parse
  :  Any* EOF -> ^(ROOT Any*)
  ;

Any
  :  .
  ;

Затем вы создаете собственный класс, который расширяет CommonTree:

demo / XTree.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class XTree extends CommonTree {

  public XTree(Token t) {
    super(t);
  }

  public void x() {
    System.out.println("XTree.text=" + super.getText() + ", children=" + super.getChildCount());
  }
}

и когда вы создаете экземпляр вашего TParser, вы должны создать и установить пользовательский TreeAdaptor, который создает экземпляры вашего XTree:

demo / Main.java

package demo;

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;

public class Main {

  public static void main(String[] args) throws Exception {
    String source = "ABC";
    TLexer lexer = new TLexer(new ANTLRStringStream(source));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    parser.setTreeAdaptor(new CommonTreeAdaptor(){
      @Override
      public Object create(Token t) {
        return new XTree(t);
      }
    }); 
    XTree root = (XTree)parser.parse().getTree();
    root.x();
  }
}

При запуске демо:

java -cp antlr-3.2.jar org.antlr.Tool T.g -o demo/
javac -cp antlr-3.2.jar demo/*.java
java -cp .:antlr-3.2.jar demo.Main

будет напечатано:

XTree.text=ROOT, children=3

Для получения дополнительной информации см .: http://www.antlr.org/wiki/display/ANTLR3/Tree+construction

...