From 15a2b29e48f134bc93cfd0a3d8512001e9242f3d Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Mon, 3 Jun 2024 17:33:53 -0400 Subject: Rename package to new domain Rename the package to the new domain --- .../pratt/blocks/RepeatingParseBlock.java | 101 +++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 JPratt/src/main/java/com/ashardalon/pratt/blocks/RepeatingParseBlock.java (limited to 'JPratt/src/main/java/com/ashardalon/pratt/blocks/RepeatingParseBlock.java') diff --git a/JPratt/src/main/java/com/ashardalon/pratt/blocks/RepeatingParseBlock.java b/JPratt/src/main/java/com/ashardalon/pratt/blocks/RepeatingParseBlock.java new file mode 100644 index 0000000..25827b4 --- /dev/null +++ b/JPratt/src/main/java/com/ashardalon/pratt/blocks/RepeatingParseBlock.java @@ -0,0 +1,101 @@ +package com.ashardalon.pratt.blocks; + +import java.util.function.UnaryOperator; + +import com.ashardalon.pratt.ParserContext; +import com.ashardalon.pratt.commands.CommandResult; +import com.ashardalon.pratt.commands.CommandResult.Status; +import com.ashardalon.pratt.tokens.Token; + +import bjc.data.Tree; +import bjc.data.SimpleTree; +import bjc.utils.parserutils.ParserException; + +/** + * A parse block that can parse a sequnce of zero or more occurances of another + * block. + * + * @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 RepeatingParseBlock implements ParseBlock { + private final ParseBlock innerBlock; + + private final K delim; + private final K term; + + private final UnaryOperator onDelim; + + private final Token mark; + + /** + * Create a new repeating block. + * + * @param inner + * The inner block for elements. + * + * @param delimiter + * The token that delimits elements in the sequence. + * + * @param terminator + * The token that terminates the sequence. + * + * @param marker + * The token to use as the node in the AST. + * + * @param action + * The action to apply to the state after every delimiter. + */ + public RepeatingParseBlock(final ParseBlock inner, final K delimiter, final K terminator, + final Token marker, final UnaryOperator action) { + super(); + + if(inner == null) + throw new NullPointerException("Inner block must not be null"); + else if(delimiter == null) + throw new NullPointerException("Delimiter must not be null"); + else if(terminator == null) throw new NullPointerException("Terminator must not be null"); + + innerBlock = inner; + + delim = delimiter; + term = terminator; + + mark = marker; + + onDelim = action; + } + + @Override + public CommandResult parse(final ParserContext ctx) throws ParserException { + final Tree> ret = new SimpleTree<>(mark); + + Token tok = ctx.tokens.current(); + + while(!tok.getKey().equals(term)) { + final CommandResult resKid = innerBlock.parse(ctx); + if (resKid.status != Status.SUCCESS) return resKid; + Tree> kid = resKid.success(); + ret.addChild(kid); + + tok = ctx.tokens.current(); + + ctx.tokens.expect(delim, term); + + if(onDelim != null) { + ctx.state = onDelim.apply(ctx.state); + } + } + + return CommandResult.success(ret); + } + +} -- cgit v1.2.3