package bjc.pratt.blocks; import java.util.Set; import bjc.pratt.ParserContext; import bjc.pratt.tokens.Token; import bjc.data.ITree; import bjc.data.Tree; import bjc.utils.parserutils.ParserException; /** * A {@link ParseBlock} for a series of parse blocks, linked by a set of tokens. * * Roughly analogous to Perl 6s list associative operators. * * @author bjculkin * * @param * The token key type. * * @param * The token value type. * * @param * The parser state type. * */ public class ChainParseBlock implements ParseBlock { private ParseBlock iner; private Set indicators; private Token trm; /** * Create a new chain parser block. * * @param inner * The block for the chains interior. * * @param chainIndicators * The set of markers that indicate continuing the chain * * @param term * The node in the AST for the expression. */ public ChainParseBlock(ParseBlock inner, Set chainIndicators, Token term) { iner = inner; indicators = chainIndicators; trm = term; } @Override public ITree> parse(ParserContext ctx) throws ParserException { ITree> expression = iner.parse(ctx); Token currentToken = ctx.tokens.current(); if(indicators.contains(currentToken.getKey())) { ITree> res = new Tree<>(trm); res.addChild(expression); while(indicators.contains(currentToken.getKey())) { res.addChild(new Tree<>(currentToken)); ctx.tokens.next(); ITree> innerExpression = iner.parse(ctx); res.addChild(innerExpression); currentToken = ctx.tokens.current(); } return res; } return expression; } }