Хорошо, после вашего РЕДАКТИРОВАНИЯ у меня есть пара рекомендаций.
Как я уже говорил в комментариях, написание грамматики для такого языка практически невозможно. По крайней мере, пытаясь сделать это за один раз, то есть. Единственный способ увидеть эту работу - это сделать это с несколькими синтаксическими анализаторами, где первая «стадия синтаксического анализа» будет анализировать источник вики очень «грубо». Например: table
будет размечен как: TABLE : '{|' .* '|}'
, и тогда вы создадите другой анализатор, который правильно анализирует эту таблицу. Выполнение этого в одном парсере приведет к множеству двусмысленностей в правилах парсера IMO.
Что касается выдачи HTML-кода, «правильный» способ сделать это действительно с StringTemplate, но, учитывая тот факт, что вы довольно плохо знакомы с самой ANTLR, я бы упростил задачу. Вы можете создать атрибут StringBuilder в своем классе синтаксического анализатора, который будет собирать весь ваш HTML-код при разборе исходного файла. Вы можете встроить код в правила ANTLR, заключив его в {
и }
.
Вот короткая демонстрация:
grammar T;
@parser::members {
// an attribute that is only available in your
// parser (so only in parser rules!)
protected StringBuilder htmlBuilder = new StringBuilder();
}
// Parser rules
parse
: atom+ EOF
;
atom
: header
| Any {htmlBuilder.append($Any.text);} // append the text from 'Any' token
;
header
: H3 h3Content H3 {htmlBuilder.append("<h3>" + $h3Content.text + "</h3>");}
| H2 h2Content H2 {htmlBuilder.append("<h2>" + $h2Content.text + "</h2>");}
| H1 h1Content H1 {htmlBuilder.append("<h1>" + $h1Content.text + "</h1>");}
;
h3Content : ~H3*; // match any token except H3, zero or more times
h2Content : ~H2*; // " H2 "
h1Content : ~H1*; // " H1 "
// Lexer rules
H3 : '===';
H2 : '==';
H1 : '=';
// Fall through rule: if non of the above
// lexer rules matched, this one will.
Any
: .
;
Из этой грамматики вы генерируете синтаксический анализатор и лексер:
java -cp antlr-3.2.jar org.antlr.Tool T.g
, а затем создайте небольшой класс для проверки вашего синтаксического анализатора:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
// the source to be parsed
String source =
"= header 1 = \n"+
" \n"+
"some text here \n"+
" \n"+
"=== header level 3 === \n"+
" \n"+
"and some more text ";
ANTLRStringStream in = new ANTLRStringStream(source);
TLexer lexer = new TLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
TParser parser = new TParser(tokens);
// invoke the start-rule in your parser
parser.parse();
// print the contents of your parser's StringBuilder
System.out.println(parser.htmlBuilder);
}
}
и затем скомпилируйте все ваши исходные файлы:
javac -cp antlr-3.2.jar *.java
и, наконец, запустить свой основной класс
// *nix & MacOS
java -cp .:antlr-3.2.jar Main
// Windows
java -cp .;antlr-3.2.jar Main
, который выведет на консоль следующее:
<h1> header 1 </h1>
some text here
<h3> header level 3 </h3>
and some more text
Но, опять же, если вы можете свободно выбирать другой язык для разбора, я бы сделал это и забыл о парсинге этой ужасной вики-штуки.
В любом случае, что бы вы ни делали: удачи!