我们对文本模板有一些特殊要求,这些要求无法通过任何常见的包(T4、NVelocity、StringTemplate..)来解决。所以我们决定尝试我们自己的,使用 Irony。
鉴于 <%%> 标记内的任何内容都是表达式的简单形式,否则只是文本文字:
Hi <% u.FirstName %> This is some template text.
我从这个开始:
// Terminals
var text = new FreeTextLiteral("FreeTextLiteral", FreeTextOptions.AllowEof | FreeTextOptions.ConsumeTerminator, "<");
text.Escapes.Add(@"\<", "<");
var identifierTerminal = new IdentifierTerminal("identifierTerminal");
var expressionStart = new KeyTerm("%", "ExpressionStart");
var expressionEnd = new KeyTerm("%>", "ExpressionEnd");
// Non terminals
var statement = new NonTerminal("Statement");
var template = new NonTerminal("Template", typeof(StatementListNode));
var expression = new NonTerminal("Expression", typeof(ExpressionListNode));
var memberExpression = new NonTerminal("MemberExpression");
// Rules
statement.Rule = text | expression;
expression.Rule = expressionStart + memberExpression + expressionEnd;
memberExpression.Rule = identifierTerminal + "." + identifierTerminal;
template.Rule = MakePlusRule(template, null, statement);
问题是在解析上面的提取后检查根节点,有两个子节点,它们都是freetextliteral节点。
如何防止 Freetextliteral 消耗所有输入?
谢谢!