似乎我终于抓住了模板的想法:)模板应该“嵌套”到另一个层次结构。下面的示例可以很好地工作:
模板测试g:
grammar TemplatesTest;
options
{
output=template;
language=CSharp2;
}
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : '0'..'9'+
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
doc
: (e+=expr)+ -> doc(expressions={$e})
;
expr
: ID '=' INT -> expression(id={$ID.text}, value={$INT.text})
;
模板测试.stg:
group TemplatesTest;
doc(expressions) ::=
<<
srart expressions
<expressions; separator="\n">
end
>>
expression(id, value) ::=
<<
<id> := <value>;
>>
测试C代码:
var lexer = new TemplatesTestLexer(new ANTLRFileStream("sample.txt"));
var parser = new TemplatesTestParser(new CommonTokenStream(lexer));
using (var reader = new StreamReader("TemplatesTest.stg"))
{
parser.TemplateLib = new StringTemplateGroup(reader);
}
var doc = parser.doc();
Console.WriteLine(doc.Template);
样本输入:
a = 5
b = 6
c = 7
输出为:
srart expressions
a := 5;
b := 6;
c := 7;
end