我会遇到这个问题: 鉴于此规则
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的*中,也就是说,如何根据'*'编写模板来执行上面描述的内容?
谢谢你!!!
答案 0 :(得分:6)
使用VAR
运算符收集java.util.List
中的所有+=
代币:
defField
: t=type v+=VAR (',' v+=VAR)* SEP
;
现在v
(列表)包含所有VAR
。
然后将t
和v
作为参数传递给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}}包括其后面的文本不应该是命令的一部分:这些只是用于指示这些命令的用途的注释。