summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/dice/ast
diff options
context:
space:
mode:
authorbculkin2442 <bjculkin@mix.wvu.edu>2016-03-22 12:28:35 -0400
committerbculkin2442 <bjculkin@mix.wvu.edu>2016-03-22 12:28:35 -0400
commit01cb9f504c860bc1c037a44f3a76bf342a293d46 (patch)
tree02d1d34de0828159bbda93e881c93a6b45720f32 /BJC-Utils2/src/main/java/bjc/utils/dice/ast
parent4685955a62c430007c5c8ed2b915ffc618d30aca (diff)
General formatting cleanup and documentation update
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/dice/ast')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTExpression.java142
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFlattener.java67
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFreezer.java65
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java70
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/IDiceASTNode.java11
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/LiteralDiceNode.java22
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/OperatorDiceNode.java64
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/dice/ast/VariableDiceNode.java37
8 files changed, 367 insertions, 111 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTExpression.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTExpression.java
index 3b81888..aceeed0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTExpression.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTExpression.java
@@ -12,48 +12,22 @@ import bjc.utils.dice.CompoundDice;
import bjc.utils.dice.IDiceExpression;
import bjc.utils.parserutils.AST;
+/**
+ * An implementation of {@link IDiceExpression} backed by an AST of
+ * {@link IDiceASTNode}s
+ *
+ * @author ben
+ *
+ */
public class DiceASTExpression implements IDiceExpression {
- private AST<IDiceASTNode> ast;
- private Map<String, DiceASTExpression> env;
-
- public DiceASTExpression(AST<IDiceASTNode> ast,
- Map<String, DiceASTExpression> env) {
- this.ast = ast;
- this.env = env;
- }
-
- private Pair<Integer, AST<IDiceASTNode>> evalLeaf(IDiceASTNode tokn) {
- if (tokn instanceof VariableDiceNode) {
- String varName = ((VariableDiceNode) tokn).getVariable();
-
- if (env.containsKey(varName)) {
- return new Pair<>(env.get(varName).roll(), new AST<>(tokn));
- } else {
- // Handle special case for defining variables
- return new Pair<>(0, new AST<>(tokn));
- }
- } else {
- LiteralDiceNode lnod = (LiteralDiceNode) tokn;
- String dat = lnod.getData();
-
- if (StringUtils.countMatches(dat, 'c') == 1
- && !dat.equalsIgnoreCase("c")) {
- String[] strangs = dat.split("c");
- return new Pair<>(new CompoundDice(strangs).roll(),
- new AST<>(tokn));
- } else if (StringUtils.countMatches(dat, 'd') == 1
- && !dat.equalsIgnoreCase("d")) {
- /*
- * Handle dice groups
- */
- return new Pair<>(ComplexDice.fromString(dat).roll(),
- new AST<>(tokn));
- } else {
- return new Pair<>(Integer.parseInt(dat), new AST<>(tokn));
- }
- }
- }
+ /**
+ * Build the map of operations to use when collapsing the AST
+ *
+ * @param env
+ * The enviroment to evaluate bindings and such against
+ * @return The operations to use when collapsing the AST
+ */
private static
Map<IDiceASTNode, BinaryOperator<Pair<Integer, AST<IDiceASTNode>>>>
buildOperations(Map<String, DiceASTExpression> env) {
@@ -121,6 +95,83 @@ public class DiceASTExpression implements IDiceExpression {
return opCollapsers;
}
+ /**
+ * The AST this expression will evaluate
+ */
+ private AST<IDiceASTNode> ast;
+
+ /**
+ * The enviroment to evaluate bindings and such against
+ */
+ private Map<String, DiceASTExpression> env;
+
+ /**
+ * Create a new dice expression backed by an AST
+ *
+ * @param ast
+ * The AST backing this expression
+ * @param env
+ * The enviroment to evaluate bindings against
+ */
+ public DiceASTExpression(AST<IDiceASTNode> ast,
+ Map<String, DiceASTExpression> env) {
+ this.ast = ast;
+ this.env = env;
+ }
+
+ /**
+ * Expand a leaf AST token into a pair for evaluation
+ *
+ * @param tokn
+ * The token to evaluate
+ * @return A pair consisting of the token's value and the AST it
+ * represents
+ */
+ private Pair<Integer, AST<IDiceASTNode>> evalLeaf(IDiceASTNode tokn) {
+ if (tokn instanceof VariableDiceNode) {
+ String varName = ((VariableDiceNode) tokn).getVariable();
+
+ if (env.containsKey(varName)) {
+ return new Pair<>(env.get(varName).roll(),
+ new AST<>(tokn));
+ } else {
+ // Handle special case for defining variables
+ return new Pair<>(0, new AST<>(tokn));
+ }
+ } else {
+ LiteralDiceNode lnod = (LiteralDiceNode) tokn;
+ String dat = lnod.getData();
+
+ if (StringUtils.countMatches(dat, 'c') == 1
+ && !dat.equalsIgnoreCase("c")) {
+ String[] strangs = dat.split("c");
+ return new Pair<>(new CompoundDice(strangs).roll(),
+ new AST<>(tokn));
+ } else if (StringUtils.countMatches(dat, 'd') == 1
+ && !dat.equalsIgnoreCase("d")) {
+ /*
+ * Handle dice groups
+ */
+ return new Pair<>(ComplexDice.fromString(dat).roll(),
+ new AST<>(tokn));
+ } else {
+ return new Pair<>(Integer.parseInt(dat), new AST<>(tokn));
+ }
+ }
+ }
+
+ /**
+ * Get the AST bound to this expression
+ * @return the ast
+ */
+ public AST<IDiceASTNode> getAst() {
+ return ast;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see bjc.utils.dice.IDiceExpression#roll()
+ */
@Override
public int roll() {
Map<IDiceASTNode, BinaryOperator<Pair<Integer, AST<IDiceASTNode>>>> operations =
@@ -130,15 +181,12 @@ public class DiceASTExpression implements IDiceExpression {
(r) -> r.merge((left, right) -> left));
}
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
@Override
public String toString() {
return ast.toString();
}
-
- /**
- * @return the ast
- */
- public AST<IDiceASTNode> getAst() {
- return ast;
- }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFlattener.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFlattener.java
index da402c3..70465a5 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFlattener.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFlattener.java
@@ -16,25 +16,25 @@ import bjc.utils.dice.ReferenceDiceExpression;
import bjc.utils.dice.ScalarDie;
import bjc.utils.parserutils.AST;
+/**
+ * Flatten an {@link AST} of {@link IDiceASTNode} into a
+ * {@link IDiceExpression}
+ *
+ * @author ben
+ *
+ */
public class DiceASTFlattener {
- public static IDiceExpression flatten(AST<IDiceASTNode> ast,
- Map<String, IDiceExpression> env) {
- Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers = buildOperations(
- env);
-
- return ast.collapse((nod) -> {
- if (nod instanceof LiteralDiceNode) {
- return expFromLiteral((LiteralDiceNode) nod);
- } else {
- return new ReferenceDiceExpression(
- ((VariableDiceNode) nod).getVariable(), env);
- }
- } , opCollapsers::get, (r) -> r);
- }
-
- private static Map<IDiceASTNode, BinaryOperator<IDiceExpression>> buildOperations(
- Map<String, IDiceExpression> env) {
- Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers = new HashMap<>();
+ /**
+ * Build the operations to use for tree flattening
+ *
+ * @param env
+ * The enviroment the tree will be flattened against
+ * @return The operations needed for tree flattening
+ */
+ private static Map<IDiceASTNode, BinaryOperator<IDiceExpression>>
+ buildOperations(Map<String, IDiceExpression> env) {
+ Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers =
+ new HashMap<>();
opCollapsers.put(OperatorDiceNode.ADD, (left, right) -> {
return new CompoundDiceExpression(right, left,
DiceExpressionType.ADD);
@@ -64,6 +64,13 @@ public class DiceASTFlattener {
return opCollapsers;
}
+ /**
+ * Create a dice expression from a literal token
+ *
+ * @param tok
+ * The token to convert to an expression
+ * @return The dice expression represented by the token
+ */
private static IDiceExpression expFromLiteral(LiteralDiceNode tok) {
String data = tok.getData();
@@ -80,4 +87,28 @@ public class DiceASTFlattener {
return new ScalarDie(Integer.parseInt(data));
}
}
+
+ /**
+ * Flatten a AST into a dice expression
+ *
+ * @param ast
+ * The AST to flatten
+ * @param env
+ * The enviroment to flatten against
+ * @return The AST, flattened into a dice expression
+ */
+ public static IDiceExpression flatten(AST<IDiceASTNode> ast,
+ Map<String, IDiceExpression> env) {
+ Map<IDiceASTNode, BinaryOperator<IDiceExpression>> opCollapsers =
+ buildOperations(env);
+
+ return ast.collapse((nod) -> {
+ if (nod instanceof LiteralDiceNode) {
+ return expFromLiteral((LiteralDiceNode) nod);
+ } else {
+ return new ReferenceDiceExpression(
+ ((VariableDiceNode) nod).getVariable(), env);
+ }
+ } , opCollapsers::get, (r) -> r);
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFreezer.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFreezer.java
index 04cc99b..efe37c0 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFreezer.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTFreezer.java
@@ -4,7 +4,52 @@ import java.util.Map;
import bjc.utils.parserutils.AST;
+/**
+ * Freeze references in a dice AST, replacing variable references with what
+ * the variables refer to
+ *
+ * @author ben
+ *
+ */
public class DiceASTFreezer {
+ /**
+ * Expand a reference
+ *
+ * @param vnode
+ * The node containing the reference to expand
+ * @param env
+ * The enviroment to expand against
+ * @return The expanded reference
+ */
+ private static AST<IDiceASTNode> expandNode(VariableDiceNode vnode,
+ Map<String, AST<IDiceASTNode>> env) {
+ return env.get(vnode.getVariable());
+ }
+
+ /**
+ * Expand a reference
+ *
+ * @param vnode
+ * The node containing the reference to expand
+ * @param env
+ * The enviroment to expand against
+ * @return The expanded reference
+ */
+ private static AST<IDiceASTNode> expandNode2(VariableDiceNode vnode,
+ Map<String, DiceASTExpression> env) {
+ return env.get(vnode.getVariable()).getAst();
+ }
+
+ /**
+ * Freeze the references in an AST
+ *
+ * @param tree
+ * The tree to freeze references in
+ * @param env
+ * The enviroment to get reference values from
+ * @return The tree with references frozen
+ */
+ @SuppressWarnings("unused")
public static AST<IDiceASTNode> freezeAST(AST<IDiceASTNode> tree,
Map<String, AST<IDiceASTNode>> env) {
return tree.collapse((nod) -> {
@@ -20,6 +65,16 @@ public class DiceASTFreezer {
} , (r) -> r);
}
+ /**
+ * Freeze the references in an expression backed by an AST
+ *
+ * @param tree
+ * The tree-backed expression to freeze references in
+ * @param env
+ * The enviroment to get reference values from
+ * @return The tree with references frozen
+ */
+ @SuppressWarnings("unused")
public static AST<IDiceASTNode> freezeAST(DiceASTExpression tree,
Map<String, DiceASTExpression> env) {
return tree.getAst().collapse((nod) -> {
@@ -34,14 +89,4 @@ public class DiceASTFreezer {
return new AST<IDiceASTNode>(op, left, right);
} , (r) -> r);
}
-
- private static AST<IDiceASTNode> expandNode(VariableDiceNode vnode,
- Map<String, AST<IDiceASTNode>> env) {
- return env.get(vnode.getVariable());
- }
-
- private static AST<IDiceASTNode> expandNode2(VariableDiceNode vnode,
- Map<String, DiceASTExpression> env) {
- return env.get(vnode.getVariable()).getAst();
- }
}
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
index d56ad0e..b25f5b4 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/DiceASTParser.java
@@ -8,7 +8,16 @@ import bjc.utils.parserutils.AST;
import bjc.utils.parserutils.ShuntingYard;
import bjc.utils.parserutils.TreeConstructor;
+/**
+ * Create an AST from a string expression
+ *
+ * @author ben
+ *
+ */
public class DiceASTParser {
+ /**
+ * The yard to use for shunting expressions
+ */
private static ShuntingYard<String> yard;
static {
@@ -22,14 +31,21 @@ public class DiceASTParser {
// expression
}
+ /**
+ * Build an AST from a string expression
+ *
+ * @param exp
+ * The string to build from
+ * @return An AST built from the passed in string
+ */
public AST<IDiceASTNode> buildAST(String exp) {
- FunctionalList<String> tokens = FunctionalStringTokenizer
- .fromString(exp).toList((s) -> s);
+ FunctionalList<String> tokens =
+ FunctionalStringTokenizer.fromString(exp).toList((s) -> s);
FunctionalList<String> shunted = yard.postfix(tokens, (s) -> s);
- AST<String> rawAST = TreeConstructor.constructTree(shunted,
- this::isOperator);
+ AST<String> rawAST =
+ TreeConstructor.constructTree(shunted, this::isOperator);
AST<IDiceASTNode> bakedAST = rawAST.transmuteAST((tok) -> {
if (isOperator(tok)) {
@@ -44,22 +60,14 @@ public class DiceASTParser {
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) {
+ /**
+ * Check if a token represents a literal
+ *
+ * @param tok
+ * The token to check
+ * @return Whether or not the token represents a literal
+ */
+ private static boolean isLiteral(String tok) {
if (StringUtils.countMatches(tok, 'c') == 1
&& !tok.equalsIgnoreCase("c")) {
return true;
@@ -75,4 +83,26 @@ public class DiceASTParser {
}
}
}
+
+ /**
+ * Check if a token represents an operator
+ *
+ * @param tok
+ * The token to check if it represents an operator
+ * @return Whether or not the token represents an operator
+ */
+ private boolean isOperator(String tok) {
+ switch (tok) {
+ case ":=":
+ case "+":
+ case "-":
+ case "*":
+ case "/":
+ case "c":
+ case "d":
+ return true;
+ default:
+ return false;
+ }
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/IDiceASTNode.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/IDiceASTNode.java
index 3fb14fe..073da89 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/IDiceASTNode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/IDiceASTNode.java
@@ -1,5 +1,16 @@
package bjc.utils.dice.ast;
+/**
+ * The interface for a node in a dice AST
+ *
+ * @author ben
+ *
+ */
public interface IDiceASTNode {
+ /**
+ * Check if this node represents an operator or not
+ *
+ * @return Whether or not this node represents an operator
+ */
public boolean isOperator();
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/LiteralDiceNode.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/LiteralDiceNode.java
index 20358fb..b0c1400 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/LiteralDiceNode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/LiteralDiceNode.java
@@ -1,8 +1,23 @@
package bjc.utils.dice.ast;
+/**
+ * A AST node that represents a literal value
+ *
+ * @author ben
+ *
+ */
public class LiteralDiceNode implements IDiceASTNode {
+ /**
+ * The value contained by this node
+ */
private String data;
+ /**
+ * Create a new node with the given value
+ *
+ * @param data
+ * The value to be in this node
+ */
public LiteralDiceNode(String data) {
this.data = data;
}
@@ -20,7 +35,12 @@ public class LiteralDiceNode implements IDiceASTNode {
public String getData() {
return data;
}
-
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
@Override
public String toString() {
return data;
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/OperatorDiceNode.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/OperatorDiceNode.java
index 92b49b7..c4f7763 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/OperatorDiceNode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/OperatorDiceNode.java
@@ -4,16 +4,51 @@ package bjc.utils.dice.ast;
// 1. DiceASTExpression
// 2. DiceASTFlattener
// 3. DiceASTParser
+/**
+ * A node that represents an operator
+ *
+ * @author ben
+ *
+ */
public enum OperatorDiceNode implements IDiceASTNode {
- ASSIGN, ADD, SUBTRACT, MULTIPLY, DIVIDE, GROUP, COMPOUND;
-
- @Override
- public boolean isOperator() {
- return true;
- }
-
+ /**
+ * Represents adding two nodes
+ */
+ ADD,
+ /**
+ * Represents assigning one node to another
+ */
+ ASSIGN,
+ /**
+ * Representings combining two node values together
+ */
+ COMPOUND,
+ /**
+ * Represents dividing two nodes
+ */
+ DIVIDE,
+ /**
+ * Represents using one node a variable number of times
+ */
+ GROUP,
+ /**
+ * Represents multiplying two nodes
+ */
+ MULTIPLY,
+ /**
+ * Represents subtracting two nodes
+ */
+ SUBTRACT;
+
+ /**
+ * Create a operator node from a string
+ *
+ * @param s
+ * The string to convert to a node
+ * @return The operator corresponding to the node
+ */
public static OperatorDiceNode fromString(String s) {
- switch(s) {
+ switch (s) {
case ":=":
return ASSIGN;
case "+":
@@ -29,7 +64,18 @@ public enum OperatorDiceNode implements IDiceASTNode {
case "c":
return COMPOUND;
default:
- throw new IllegalArgumentException(s + " is not a valid operator node");
+ throw new IllegalArgumentException(
+ s + " is not a valid operator node");
}
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see bjc.utils.dice.ast.IDiceASTNode#isOperator()
+ */
+ @Override
+ public boolean isOperator() {
+ return true;
+ }
}
diff --git a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/VariableDiceNode.java b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/VariableDiceNode.java
index 6ae3189..43a09b2 100644
--- a/BJC-Utils2/src/main/java/bjc/utils/dice/ast/VariableDiceNode.java
+++ b/BJC-Utils2/src/main/java/bjc/utils/dice/ast/VariableDiceNode.java
@@ -1,17 +1,27 @@
package bjc.utils.dice.ast;
+/**
+ * A node that represents a variable reference
+ *
+ * @author ben
+ *
+ */
public class VariableDiceNode implements IDiceASTNode {
+ /**
+ * The variable referenced by this node
+ */
private String var;
+ /**
+ * Create a new node representing the specified variable
+ *
+ * @param data
+ * The name of the variable being referenced
+ */
public VariableDiceNode(String data) {
this.var = data;
}
- @Override
- public boolean isOperator() {
- return false;
- }
-
/**
* Get the variable referenced by this AST node
*
@@ -20,7 +30,22 @@ public class VariableDiceNode implements IDiceASTNode {
public String getVariable() {
return var;
}
-
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see bjc.utils.dice.ast.IDiceASTNode#isOperator()
+ */
+ @Override
+ public boolean isOperator() {
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
@Override
public String toString() {
return var;