package bjc.pratt.commands.impls; import java.util.Set; import bjc.pratt.ParserContext; import bjc.pratt.commands.BinaryPostCommand; import bjc.pratt.commands.CommandResult; import bjc.pratt.commands.CommandResult.Status; import bjc.pratt.tokens.Token; import bjc.data.Tree; import bjc.data.SimpleTree; 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 CommandResult denote(final Tree> operand, final Token operator, final ParserContext ctx) throws ParserException { CommandResult resOuter = ctx.parse.parseExpression(1 + leftBinding(), ctx.tokens, ctx.state, false); if (resOuter.status != Status.SUCCESS) return resOuter; final Tree> tree = resOuter.success(); final Tree> res = new SimpleTree<>(operator, operand, tree); if(chainWith.contains(ctx.tokens.current().getKey())) { final Token tok = ctx.tokens.current(); ctx.tokens.next(); CommandResult resOther = denote(tree, tok, new ParserContext<>(ctx.tokens, ctx.parse, ctx.state)); if (resOther.status != Status.SUCCESS) return resOther; final Tree> other = resOther.success(); return CommandResult.success(new SimpleTree<>(chain, res, other)); } return CommandResult.success(res); } @Override public int nextBinding() { return leftBinding() - 1; } }