From 7549e7d1b671738d9ebe9a6bf12b666b2bcb5b42 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 21 Mar 2016 17:57:12 -0400 Subject: Built AST representation of Dice things --- .../java/bjc/utils/dice/ast/DiceASTParser.java | 78 ++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java (limited to 'BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java') diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java new file mode 100644 index 0000000..d56ad0e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java @@ -0,0 +1,78 @@ +package bjc.utils.dice.ast; + +import org.apache.commons.lang3.StringUtils; + +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.FunctionalStringTokenizer; +import bjc.utils.parserutils.AST; +import bjc.utils.parserutils.ShuntingYard; +import bjc.utils.parserutils.TreeConstructor; + +public class DiceASTParser { + private static ShuntingYard yard; + + static { + yard = new ShuntingYard<>(); + + yard.addOp("d", 5); // dice operator: use for creating variable + // size dice groups + yard.addOp("c", 6); // compound operator: use for creating compound + // dice from expressions + yard.addOp(":=", 0); // binding operator: Bind a name to a variable + // expression + } + + public AST buildAST(String exp) { + FunctionalList tokens = FunctionalStringTokenizer + .fromString(exp).toList((s) -> s); + + FunctionalList shunted = yard.postfix(tokens, (s) -> s); + + AST rawAST = TreeConstructor.constructTree(shunted, + this::isOperator); + + AST bakedAST = rawAST.transmuteAST((tok) -> { + if (isOperator(tok)) { + return OperatorDiceNode.fromString(tok); + } else if (isLiteral(tok)) { + return new LiteralDiceNode(tok); + } else { + return new VariableDiceNode(tok); + } + }); + + return bakedAST; + } + + private boolean isOperator(String tok) { + switch (tok) { + case ":=": + case "+": + case "-": + case "*": + case "/": + case "c": + case "d": + return true; + default: + return false; + } + } + + private boolean isLiteral(String tok) { + if (StringUtils.countMatches(tok, 'c') == 1 + && !tok.equalsIgnoreCase("c")) { + return true; + } else if (StringUtils.countMatches(tok, 'd') == 1 + && !tok.equalsIgnoreCase("d")) { + return true; + } else { + try { + Integer.parseInt(tok); + return true; + } catch (NumberFormatException nfx) { + return false; + } + } + } +} -- cgit v1.2.3