package org.jtwig.parser.parboiled.expression; import org.jtwig.model.expression.Expression; import org.jtwig.model.expression.MapExpression; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.BasicParser; import org.jtwig.parser.parboiled.base.PositionTrackerParser; import org.jtwig.parser.parboiled.base.SpacingParser; import org.parboiled.Rule; import java.util.LinkedHashMap; import java.util.Map; import static org.parboiled.Parboiled.createParser; public class MapExpressionParser extends ExpressionParser<MapExpression> { public MapExpressionParser(ParserContext context) { super(MapExpressionParser.class, context); createParser(MapParser.class, context); createParser(StringOrIdentifierParser.class, context); } @Override public Rule ExpressionRule() { SpacingParser spacingParser = parserContext().parser(SpacingParser.class); MapParser mapParser = parserContext().parser(MapParser.class); PositionTrackerParser positionTrackerParser = parserContext().parser(PositionTrackerParser.class); return Sequence( positionTrackerParser.PushPosition(), String("{"), spacingParser.Spacing(), mapParser.Expression(), String("}"), push(new MapExpression(positionTrackerParser.pop(1), mapParser.pop())) ); } public static class MapParser extends BasicParser<Map<String, Expression>> { public MapParser(ParserContext context) { super(MapParser.class, context); } public Rule Expression () { AnyExpressionParser parser = parserContext().parser(AnyExpressionParser.class); StringOrIdentifierParser stringOrIdentifierParser = parserContext().parser(StringOrIdentifierParser.class); SpacingParser spacingParser = parserContext().parser(SpacingParser.class); return Sequence( push(new LinkedHashMap<String, Expression>()), Optional( stringOrIdentifierParser.Expression(), spacingParser.Spacing(), String(":"), spacingParser.Spacing(), parser.ExpressionRule(), run(peek(2).put(stringOrIdentifierParser.pop(1), parser.pop())), ZeroOrMore( spacingParser.Spacing(), String(","), spacingParser.Spacing(), stringOrIdentifierParser.Expression(), spacingParser.Spacing(), String(":"), spacingParser.Spacing(), parser.ExpressionRule(), run(peek(2).put(stringOrIdentifierParser.pop(1), parser.pop())) ) ) ); } public boolean run (Object value) { return true; } } public static class StringOrIdentifierParser extends BasicParser<String> { public StringOrIdentifierParser(ParserContext context) { super(StringOrIdentifierParser.class, context); } public Rule Expression () { StringExpressionParser stringExpressionParser = parserContext().parser(StringExpressionParser.class); NumberExpressionParser numberExpressionParser = parserContext().parser(NumberExpressionParser.class); VariableExpressionParser variableExpressionParser = parserContext().parser(VariableExpressionParser.class); return FirstOf( Sequence( stringExpressionParser.ExpressionRule(), push(stringExpressionParser.pop().getConstantValue().toString()) ), Sequence( numberExpressionParser.ExpressionRule(), push(numberExpressionParser.pop().getConstantValue().toString()) ), Sequence( variableExpressionParser.ExpressionRule(), push(variableExpressionParser.pop().getIdentifier()) ) ); } } }