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())
)
);
}
}
}