From c82e3b3b2de0633317ec8fc85925e91422820597 Mon Sep 17 00:00:00 2001 From: "Benjamin J. Culkin" Date: Sun, 8 Oct 2017 22:39:59 -0300 Subject: Start splitting into maven modules --- .../bjc/utils/parserutils/TreeConstructor.java | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 base/src/main/java/bjc/utils/parserutils/TreeConstructor.java (limited to 'base/src/main/java/bjc/utils/parserutils/TreeConstructor.java') diff --git a/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java new file mode 100644 index 0000000..90141ef --- /dev/null +++ b/base/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -0,0 +1,125 @@ +package bjc.utils.parserutils; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.function.Function; +import java.util.function.Predicate; + +import bjc.utils.data.IHolder; +import bjc.utils.data.IPair; +import bjc.utils.data.ITree; +import bjc.utils.data.Identity; +import bjc.utils.data.Pair; +import bjc.utils.funcdata.IList; + +/** + * Creates a parse tree from a postfix expression + * + * @author ben + * + */ +public class TreeConstructor { + /** + * Alias interface for special operator types. + * + * @param + * The token type of the tree. + */ + public interface QueueFlattener extends Function>, ITree> { + + } + + /* + * Alias for constructor state. + */ + static final class ConstructorState extends Pair>, ITree> { + public ConstructorState(final Deque> left, final ITree right) { + super(left, right); + } + + public ConstructorState(final IPair>, ITree> par) { + super(par.getLeft(), par.getRight()); + } + } + + /** + * Construct a tree from a list of tokens in postfix notation + * + * Only binary operators are accepted. + * + * @param + * The elements of the parse tree + * @param tokens + * The list of tokens to build a tree from + * @param isOperator + * The predicate to use to determine if something is a + * operator + * @return A AST from the expression + */ + public static ITree constructTree(final IList tokens, + final Predicate isOperator) { + /* + * Construct a tree with no special operators + */ + return constructTree(tokens, isOperator, op -> false, null); + } + + /** + * Construct a tree from a list of tokens in postfix notation. + * + * Only binary operators are accepted by default. Use the last two + * parameters to handle non-binary operators. + * + * @param + * The elements of the parse tree. + * + * @param tokens + * The list of tokens to build a tree from. + * + * @param isOperator + * The predicate to use to determine if something is a + * operator. + * + * @param isSpecialOperator + * The predicate to use to determine if an operator needs + * special handling. + * + * @param handleSpecialOperator + * The function to use to handle special case operators. + * + * @return A AST from the expression + * + */ + public static ITree constructTree(final IList tokens, + final Predicate isOperator, final Predicate isSpecialOperator, + final Function> handleSpecialOperator) { + /* + * Make sure our parameters are valid + */ + if (tokens == null) + throw new NullPointerException("Tokens must not be null"); + else if (isOperator == null) + throw new NullPointerException("Operator predicate must not be null"); + else if (isSpecialOperator == null) + throw new NullPointerException("Special operator determiner must not be null"); + + /* + * Here is the state for the tree construction + */ + final IHolder> initialState = new Identity<>( + new ConstructorState<>(new LinkedList<>(), null)); + + /* + * Transform each of the tokens + */ + tokens.forEach(new TokenTransformer<>(initialState, isOperator, isSpecialOperator, + handleSpecialOperator)); + + /* + * Grab the tree from the state + */ + return initialState.unwrap(pair -> { + return pair.getRight(); + }); + } +} -- cgit v1.2.3