package org.jtwig.parser.parboiled.expression.test; import org.jtwig.model.expression.test.NotTestExpression; import org.jtwig.model.expression.test.TestExpression; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.BasicParser; import org.jtwig.parser.parboiled.base.LexicParser; import org.jtwig.parser.parboiled.base.SpacingParser; import org.jtwig.parser.parboiled.model.Keyword; import org.parboiled.Rule; import java.util.List; import static org.parboiled.Parboiled.createParser; public class AnyTestExpressionParser extends TestExpressionParser<TestExpression> { private final List<Class<? extends TestExpressionParser>> testExpressionParsers; public AnyTestExpressionParser(ParserContext context, List<Class<? extends TestExpressionParser>> testExpressionParsers) { super(AnyTestExpressionParser.class, context); this.testExpressionParsers = testExpressionParsers; createParser(NotParser.class, context); } @Override public Rule Test() { NotParser notParser = parserContext().parser(NotParser.class); TestExpressionParser[] parsers = new TestExpressionParser[testExpressionParsers.size()]; for (int i = 0; i < parsers.length; i++) { parsers[i] = parserContext().parser(testExpressionParsers.get(i)); } return Sequence( notParser.Rule(), FirstOf(rulesFor(parsers, notParser)) ); } Rule[] rulesFor(TestExpressionParser[] parsers, NotParser notParser) { Rule[] rules = new Rule[parsers.length]; for (int i = 0; i < parsers.length; i++) { rules[i] = ruleFor(parsers[i], notParser); } return rules; } Rule ruleFor(TestExpressionParser parser, NotParser notParser) { return Sequence( parser.Test(), push(NotTestExpression.create(notParser.pop(1), (TestExpression) parser.pop())) ); } public static class NotParser extends BasicParser<Boolean> { public NotParser(ParserContext context) { super(NotParser.class, context); } public Rule Rule () { return FirstOf( Sequence( parserContext().parser(LexicParser.class).Keyword(Keyword.NOT), parserContext().parser(SpacingParser.class).Spacing(), push(true) ), push(false) ); } } }