package org.jtwig.parser.parboiled.expression.operator; import org.jtwig.parser.parboiled.ParserContext; import org.jtwig.parser.parboiled.base.BasicParser; import org.jtwig.parser.parboiled.base.LexicParser; import org.jtwig.render.expression.calculator.operation.unary.UnaryOperator; import org.parboiled.Rule; import java.util.*; public class UnaryOperatorParser extends BasicParser<UnaryOperator> { final List<UnaryOperator> operators; public UnaryOperatorParser(ParserContext context, Collection<UnaryOperator> operators) { super(UnaryOperatorParser.class, context); this.operators = new ArrayList<>(operators); } public Rule UnaryOperator() { Collections.sort(operators, new Comparator<UnaryOperator>() { @Override public int compare(UnaryOperator o1, UnaryOperator o2) { return new Integer(o1.precedence()).compareTo(o2.precedence()); } }); Rule[] rules = new Rule[operators.size()]; for (int i = 0; i < operators.size(); i++) { rules[i] = UnaryOperator(operators.get(i)); } return FirstOf(rules); } Rule UnaryOperator(UnaryOperator unaryOperator) { if (endsWithNonSymbol(unaryOperator.symbol())) { return Sequence( String(unaryOperator.symbol()), TestNot(parserContext().parser(LexicParser.class).LetterOrDigit()), push(unaryOperator) ); } else { return Sequence( String(unaryOperator.symbol()), push(unaryOperator) ); } } boolean endsWithNonSymbol(String symbol) { return symbol.matches(".*[a-zA-Z0-9_\\$]$"); } }