package bjc.pratt.blocks; import java.util.function.Function; import bjc.pratt.ParserContext; import bjc.pratt.PrattParser; import bjc.pratt.tokens.Token; import bjc.pratt.tokens.TokenStream; import bjc.data.Tree; import bjc.functypes.*; import bjc.utils.parserutils.ParserException; /** * A {@link ParseBlock} that parses an expression from a 'inner' grammar. * * @author bjculkin * * @param * The key type of the outer tokens. * * @param * The value type of the outer tokens. * * @param * The state type of the outer parser. * * @param * The key type of the inner tokens. * * @param * The value type of the inner tokens. * * @param * The state type of the outer parser. */ public class GrammarParseBlock implements ParseBlock { private final PrattParser innr; private final int prcedence; private final boolean isStatemnt; private final Function, TokenStream> tkenTransform; private final Isomorphism stteTransform; private final Function>, Tree>> xpressionTransform; /** * Create a new grammar parser block. * * @param inner The inner grammar to parse. * @param precedence The precedence of the expression to parse. * @param isStatement Is the expression being parsed in statement context? * @param tokenTransform Function to transform to the new token type. * @param stateTransform Function to toggle between state types. * @param expressionTransform Function to transform back to the normal token type. */ public GrammarParseBlock(final PrattParser inner, final int precedence, final boolean isStatement, final Function, TokenStream> tokenTransform, final Isomorphism stateTransform, final Function>, Tree>> expressionTransform) { innr = inner; prcedence = precedence; isStatemnt = isStatement; tkenTransform = tokenTransform; stteTransform = stateTransform; xpressionTransform = expressionTransform; } @Override public Tree> parse(final ParserContext ctx) throws ParserException { final C2 newState = stteTransform.to(ctx.state); final TokenStream newTokens = tkenTransform.apply(ctx.tokens); final Tree> expression = innr.parseExpression(prcedence, newTokens, newState, isStatemnt); ctx.state = stteTransform.from(newState); return xpressionTransform.apply(expression); } }