ANTLR模板翻译器匹配语法的一部分

时间:2011-11-03 15:21:40

标签: antlr antlr3 stringtemplate

我为一种语言编写了一个语法,现在我想处理一些语法糖结构,因为我正在考虑编写一个模板翻译器。

问题是我希望我的模板语法只翻译语言的一些结构,并保留原样。

例如:

我将此作为输入:

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>);

我希望将剩下的输入与规则decl不匹配。

如果没有为该语言编写完整的语法,我怎样才能在ANTLR中实现这一目标?

1 个答案:

答案 0 :(得分:1)

我只是在解析器语法中处理这些事情。

假设您在解析器语法中构建了一个AST,我想您将有一个规则来解析像Array a = new Array(10);这样的输入,类似于:

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

其中expr最终匹配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:

enter image description here

与为输入Array a = new Array(10);创建的AST完全相同。

修改

这是一个小型的工作演示:

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);
  }
}