package bjc.pratt.commands.impls; import java.util.Set; import bjc.pratt.ParserContext; import bjc.pratt.commands.BinaryPostCommand; import bjc.pratt.tokens.Token; import bjc.utils.data.ITree; import bjc.utils.data.Tree; import bjc.utils.parserutils.ParserException; /** * Create a new chained operator. * * @author bjculkin * * @param * The key type of the tokens. * * @param * The value type of the tokens. * * @param * The state type of the parser. */ public class ChainCommand extends BinaryPostCommand { private final Set chainWith; private final Token chain; /** * Create a new chained operator. * * @param precedence * The precedence of this operator. * * @param chainSet * The operators to chain with. * * @param chainMarker * The token to use as the node in the AST. */ public ChainCommand(final int precedence, final Set chainSet, final Token chainMarker) { super(precedence); chainWith = chainSet; chain = chainMarker; } @Override public ITree> denote(final ITree> operand, final Token operator, final ParserContext ctx) throws ParserException { final ITree> tree = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false); final ITree> res = new Tree<>(operator, operand, tree); if (chainWith.contains(ctx.tokens.current().getKey())) { final Token tok = ctx.tokens.current(); ctx.tokens.next(); final ITree> other = denote(tree, tok, new ParserContext<>(ctx.tokens, ctx.parse, ctx.state)); return new Tree<>(chain, res, other); } return res; } @Override public int nextBinding() { return leftBinding() - 1; } }