2

私は言語の文法を書きましたが、今はいくつかの構文糖構造を扱いたいと思っています。そのために、テンプレート トランスレータを書くことを考えていました。

問題は、テンプレート文法で言語の一部の構造のみを翻訳し、残りはそのままにしておきたいということです。

例えば:

私はこれを入力として持っています:

class Main { 
   int a[10];
}

それを次のように翻訳したいと思います。

class Main { 
   Array a = new Array(10);
}

理想的には、ANTLRでこのように考えたいと思います

grammer Translator
options { output=template;}

    decl 
         : TYPE  ID '[' INT ']' -> template(name = {$ID.text}, size ={$INT.text}) 
              "Array <name> = new Array(<size>);

rule decl にマッチしない残りの入力はそのまま残してほしい。

言語の完全な文法を書かずに ANTLR でこれを達成するにはどうすればよいですか?

4

1 に答える 1

2

パーサー文法でそのようなことを処理するだけです。

Array a = new Array(10);パーサー文法で AST を構築していると仮定すると、次のような入力を解析するルールがあると思います。

decl
  :  TYPE ID '=' expr ';' -> ^(DECL TYPE ID expr)
  ;

whereexpr最終的には次のtermように一致します:

term
  :  NUMBER
  |  'new' ID '(' (expr (',' expr)*)? ')' -> ^('new' ID expr*)
  |  ...
  ;

省略形の宣言を説明するには、次のようint a[10];に展開するだけです。decl

decl
  :  TYPE ID '=' expr     ';' -> ^(DECL TYPE    ID expr)
  |  TYPE ID '[' expr ']' ';' -> ^(DECL 'Array' ID ^(NEW ARRAY expr))
  ;

int a[10];これにより、入力が次の AST に書き換えられます。

ここに画像の説明を入力

これは、input 用に作成された AST とまったく同じArray a = new Array(10);です。

編集

ここに小さな動作デモがあります:

grammar T;

options {
  output=AST;
}

tokens {
  ROOT;
  DECL;
  NEW='new';
  INT='int';
  ARRAY='Array';
}

parse
  :  decl+ EOF -> ^(ROOT decl+)
  ;

decl
  :  type ID '=' expr     ';' -> ^(DECL type  ID expr)
  |  type ID '[' expr ']' ';' -> ^(DECL ARRAY ID ^(NEW ARRAY expr))
  ;

expr
  :  Number
  |  NEW type '(' (expr (',' expr)*)? ')' -> ^(NEW ID expr*)
  ;

type
  :  INT
  |  ARRAY
  |  ID
  ;

ID     : ('a'..'z' | 'A'..'Z')+;
Number : '0'..'9'+;
Space  : (' ' | '\t' | '\r' | '\n') {skip();};

クラスでテストできます:

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

public class Main {
  public static void main(String[] args) throws Exception {
    String src = "Array a = new Array(10); int a[10];";
    TLexer lexer = new TLexer(new ANTLRStringStream(src));
    TParser parser = new TParser(new CommonTokenStream(lexer));
    CommonTree tree = (CommonTree)parser.parse().getTree();
    DOTTreeGenerator gen = new DOTTreeGenerator();
    StringTemplate st = gen.toDOT(tree);
    System.out.println(st);
  }
}
于 2011-11-03T18:34:28.913 に答える