package org.jtwig.parser.parboiled.node; import org.jtwig.model.expression.VariableExpression; import org.jtwig.model.tree.OverrideBlockNode; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.LexicParser; import org.jtwig.parser.parboiled.base.LimitsParser; import org.jtwig.parser.parboiled.base.PositionTrackerParser; import org.jtwig.parser.parboiled.base.SpacingParser; import org.jtwig.parser.parboiled.expression.VariableExpressionParser; import org.jtwig.parser.parboiled.model.Keyword; import org.parboiled.Rule; public class OverrideBlockNodeParser extends NodeParser<OverrideBlockNode> { public OverrideBlockNodeParser(ParserContext context) { super(OverrideBlockNodeParser.class, context); } @Override public Rule NodeRule() { LimitsParser limitsParser = parserContext().parser(LimitsParser.class); PositionTrackerParser positionTrackerParser = parserContext().parser(PositionTrackerParser.class); LexicParser lexicParser = parserContext().parser(LexicParser.class); SpacingParser spacingParser = parserContext().parser(SpacingParser.class); VariableExpressionParser variableExpressionParser = parserContext().parser(VariableExpressionParser.class); CompositeNodeParser compositeNodeParser = parserContext().parser(CompositeNodeParser.class); return Sequence( positionTrackerParser.PushPosition(), Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword(Keyword.BLOCK), spacingParser.Mandatory(), Mandatory(variableExpressionParser.ExpressionRule(), "Block identifier not specified"), spacingParser.Spacing(), Mandatory(limitsParser.endCode(), "Missing end of code island") ), compositeNodeParser.NodeRule(), Mandatory(Sequence( limitsParser.startCode(), spacingParser.Spacing(), lexicParser.Keyword(Keyword.END_BLOCK), Optional( spacingParser.Mandatory(), variableExpressionParser.ExpressionRule(), throwExceptionIfNonSameVariableName() ), spacingParser.Spacing(), Mandatory(limitsParser.endCode(), "Missing end of code island") ), "Missing endblock tag"), push(new OverrideBlockNode( positionTrackerParser.pop(2), variableExpressionParser.pop(1), compositeNodeParser.pop() )) ); } boolean throwExceptionIfNonSameVariableName() { VariableExpressionParser variableExpressionParser = parserContext().parser(VariableExpressionParser.class); VariableExpression expression = variableExpressionParser.pop(); VariableExpression original = variableExpressionParser.peek(1); if (!expression.getIdentifier().equals(original.getIdentifier())) { addError(String.format("Expecting block '%s' to end with the same identifier but found '%s' instead", original.getIdentifier(), expression.getIdentifier())); } return true; } }