Соберите все 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()
.
Демо
Возьмите следующую грамматику (файл T.g ):
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();}
;
, который можно протестировать с помощью следующего класса (файл: Main.java ):
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());
}
}
Как вы увидите, когда вы запустите этот класс, он анализирует входные данные "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">
EDIT
Чтобы запустить демонстрацию, убедитесь, что все следующие файлы находятся в одном каталоге:
T.g
(объединенный файл грамматики)
T.stg
(файл StringTemplateGroup)
antlr-3.3.jar
(последняя стабильная сборка ANTLR на момент написания статьи)
Main.java
(тестовый класс)
затем выполните следующие команды из оболочки / приглашения вашей ОС (из того же каталога, в котором находятся все файлы):
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)
Вероятно, нет необходимости упоминать, но #
, включая текст после него, не должен быть частью команд: это только комментарии, указывающие, для чего эти команды.