在Antlr中使用StringTemplate

时间:2011-05-22 15:17:02

标签: templates antlr antlr3 stringtemplate

我会遇到这个问题: 鉴于此规则

   defField: type VAR ( ',' VAR)* SEP ;  

   VAR : ('a'..'z'|'A'..'Z')+ ;

   type: 'Number'|'String' ;

   SEP : '\n'|';' ;

我需要做的是将模板与规则“defField”相关联,该规则返回表示字段的xml-schema的字符串,即:

   Number a,b,c ;-> "<xs:element name="a" type = "xs:Number"\>" ,also for b and c.

我的问题出现在Kleene的*中,也就是说,如何根据'*'编写模板来执行上面描述的内容?

谢谢你!!!

1 个答案:

答案 0 :(得分:6)

使用VAR运算符收集java.util.List中的所有+=代币:

defField
  :  t=type v+=VAR (',' v+=VAR)* SEP 
  ;  

现在v(列表)包含所有VAR

然后将tv作为参数传递给StringTemplateGroup中的方法:

defField
  :  t=type v+=VAR (',' v+=VAR)* SEP -> defFieldSchema(type={$t.text}, vars={$v})
  ;  

其中defFieldSchema(...)必须在StringTemplateGroup中声明,可能看起来像(文件: T.stg ):

group T;

defFieldSchema(type, vars) ::= <<
<vars:{ v | \<xs:element name="<v.text>" type="xs:<type>"\>
}>
>>

迭代集合的语法如下:

<COLLECTION:{ EACH_ITEM_IN_COLLECTION | TEXT_TO_EMIT }>

vars List CommonTokens包含.text以来的答案,我抓住了toString()属性,而不依赖于grammar T; options { output=template; } defField : t=type v+=VAR (',' v+=VAR)* SEP -> defFieldSchema(type={$t.text}, vars={$v}) ; type : NUMBER | STRING ; NUMBER : 'Number' ; STRING : 'String' ; VAR : ('a'..'z'|'A'..'Z')+ ; SEP : '\n' | ';' ; SPACE : ' ' {skip();} ; 方法。

演示

采用以下语法(文件 T.g ):

import org.antlr.runtime.*;
import org.antlr.stringtemplate.*;
import java.io.*;

public class Main {
  public static void main(String[] args) throws Exception {
    StringTemplateGroup group = new StringTemplateGroup(new FileReader("T.stg"));
    ANTLRStringStream in = new ANTLRStringStream("Number a,b,c;");
    TLexer lexer = new TLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    TParser parser = new TParser(tokens);
    parser.setTemplateLib(group);
    TParser.defField_return returnValue = parser.defField();
    StringTemplate st = (StringTemplate)returnValue.getTemplate();
    System.out.println(st.toString());
  }
}

可以使用以下类进行测试(文件: Main.java ):

"Number a,b,c;"

正如您将在运行此类时看到的那样,它会解析输入<xs:element name="a" type="xs:Number"> <xs:element name="b" type="xs:Number"> <xs:element name="c" type="xs:Number"> 并生成以下输出:

T.g

修改

要运行演示,请确保在同一目录中包含以下所有文件:

  • T.stg(合并的语法文件)
  • antlr-3.3.jar(StringTemplateGroup文件)
  • Main.java(撰写本文时最新的稳定ANTLR版本)
  • #(测试类)

然后从OS的shell /提示符(从所有文件所在的同一目录)执行以下命令:

java -cp antlr-3.3.jar org.antlr.Tool T.g  # generate the lexer & parser

javac -cp antlr-3.3.jar *.java             # compile all .java source files

java -cp .:antlr-3.3.jar Main              # run the main class (*nix)
                                           # or
java -cp .;antlr-3.3.jar Main              # run the main class (Windows)         

可能没有必要提及,但{{1}}包括其后面的文本不应该是命令的一部分:这些只是用于指示这些命令的用途的注释。