mirror of
https://github.com/DanilaFe/abacus
synced 2024-12-22 07:20:09 -08:00
Add TreeValue operator nodes, and parsing for them.
This commit is contained in:
parent
07d7343339
commit
9d52d55e68
|
@ -50,6 +50,9 @@ public class LexerTokenizer implements Tokenizer<Match<TokenType>>, PluginListen
|
|||
for (String operator : manager.getAllOperators()) {
|
||||
lexer.register(Pattern.sanitize(operator), TokenType.OP);
|
||||
}
|
||||
for (String operator : manager.getAllTreeValueOperators()){
|
||||
lexer.register(Pattern.sanitize(operator), TokenType.TREE_VALUE_OP);
|
||||
}
|
||||
for (String function : manager.getAllFunctions()) {
|
||||
lexer.register(Pattern.sanitize(function), TokenType.FUNCTION);
|
||||
}
|
||||
|
@ -63,6 +66,9 @@ public class LexerTokenizer implements Tokenizer<Match<TokenType>>, PluginListen
|
|||
for (String operator : manager.getAllOperators()) {
|
||||
lexer.unregister(Pattern.sanitize(operator), TokenType.OP);
|
||||
}
|
||||
for (String operator : manager.getAllTreeValueOperators()){
|
||||
lexer.unregister(Pattern.sanitize(operator), TokenType.TREE_VALUE_OP);
|
||||
}
|
||||
for (String function : manager.getAllFunctions()) {
|
||||
lexer.unregister(Pattern.sanitize(function), TokenType.FUNCTION);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||
} else if (matchType == TokenType.FUNCTION || matchType == TokenType.TREE_VALUE_FUNCTION) {
|
||||
output.add(new Match<>("", TokenType.INTERNAL_FUNCTION_END));
|
||||
tokenStack.push(match);
|
||||
} else if (matchType == TokenType.OP) {
|
||||
} else if (matchType == TokenType.OP || matchType == TokenType.TREE_VALUE_OP) {
|
||||
String tokenString = match.getContent();
|
||||
OperatorType type = typeMap.get(tokenString);
|
||||
int precedence = precedenceMap.get(tokenString);
|
||||
|
@ -70,7 +70,7 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||
}
|
||||
|
||||
if (tokenString.equals("-") && (previousType == null || previousType == TokenType.OP ||
|
||||
previousType == TokenType.OPEN_PARENTH)) {
|
||||
previousType == TokenType.TREE_VALUE_OP || previousType == TokenType.OPEN_PARENTH)) {
|
||||
from.add(0, new Match<>("`", TokenType.OP));
|
||||
continue;
|
||||
}
|
||||
|
@ -78,10 +78,12 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||
while (!tokenStack.empty() && type == OperatorType.BINARY_INFIX) {
|
||||
Match<TokenType> otherMatch = tokenStack.peek();
|
||||
TokenType otherMatchType = otherMatch.getType();
|
||||
if (!(otherMatchType == TokenType.OP || otherMatchType == TokenType.FUNCTION ||
|
||||
otherMatchType == TokenType.TREE_VALUE_FUNCTION)) break;
|
||||
if (!(otherMatchType == TokenType.OP ||
|
||||
otherMatchType == TokenType.TREE_VALUE_OP ||
|
||||
otherMatchType == TokenType.FUNCTION ||
|
||||
otherMatchType == TokenType.TREE_VALUE_FUNCTION)) break;
|
||||
|
||||
if (otherMatchType == TokenType.OP) {
|
||||
if (otherMatchType == TokenType.OP || otherMatchType == TokenType.TREE_VALUE_OP) {
|
||||
int otherPrecedence = precedenceMap.get(otherMatch.getContent());
|
||||
if (otherPrecedence < precedence ||
|
||||
(associativity == OperatorAssociativity.RIGHT && otherPrecedence == precedence)) {
|
||||
|
@ -106,7 +108,9 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||
while (!tokenStack.empty()) {
|
||||
Match<TokenType> match = tokenStack.peek();
|
||||
TokenType newMatchType = match.getType();
|
||||
if (!(newMatchType == TokenType.OP || newMatchType == TokenType.FUNCTION ||
|
||||
if (!(newMatchType == TokenType.OP ||
|
||||
newMatchType == TokenType.TREE_VALUE_OP ||
|
||||
newMatchType == TokenType.FUNCTION ||
|
||||
newMatchType == TokenType.TREE_VALUE_FUNCTION)) return null;
|
||||
output.add(tokenStack.pop());
|
||||
}
|
||||
|
@ -123,18 +127,26 @@ public class ShuntingYardParser implements Parser<Match<TokenType>>, PluginListe
|
|||
if (matches.size() == 0) return null;
|
||||
Match<TokenType> match = matches.remove(0);
|
||||
TokenType matchType = match.getType();
|
||||
if (matchType == TokenType.OP) {
|
||||
if (matchType == TokenType.OP || matchType == TokenType.TREE_VALUE_OP) {
|
||||
String operator = match.getContent();
|
||||
OperatorType type = typeMap.get(operator);
|
||||
if (type == OperatorType.BINARY_INFIX) {
|
||||
TreeNode right = constructRecursive(matches);
|
||||
TreeNode left = constructRecursive(matches);
|
||||
if (left == null || right == null) return null;
|
||||
else return new NumberBinaryNode(operator, left, right);
|
||||
if(matchType == TokenType.OP) {
|
||||
return new NumberBinaryNode(operator, left, right);
|
||||
} else {
|
||||
return new TreeValueBinaryNode(operator, left, right);
|
||||
}
|
||||
} else {
|
||||
TreeNode applyTo = constructRecursive(matches);
|
||||
if (applyTo == null) return null;
|
||||
else return new NumberUnaryNode(operator, applyTo);
|
||||
if(matchType == TokenType.OP){
|
||||
return new NumberUnaryNode(operator, applyTo);
|
||||
} else {
|
||||
return new TreeValueUnaryNode(operator, applyTo);
|
||||
}
|
||||
}
|
||||
} else if (matchType == TokenType.NUM) {
|
||||
return new NumberNode(match.getContent());
|
||||
|
|
|
@ -7,7 +7,8 @@ package org.nwapw.abacus.tree;
|
|||
public enum TokenType {
|
||||
|
||||
INTERNAL_FUNCTION_END(-1),
|
||||
ANY(0), WHITESPACE(1), COMMA(2), OP(3), NUM(4), VARIABLE(5), FUNCTION(6), TREE_VALUE_FUNCTION(6), OPEN_PARENTH(7), CLOSE_PARENTH(8);
|
||||
ANY(0), WHITESPACE(1), COMMA(2), OP(3), TREE_VALUE_OP(3),
|
||||
NUM(4), VARIABLE(5), FUNCTION(6), TREE_VALUE_FUNCTION(6), OPEN_PARENTH(7), CLOSE_PARENTH(8);
|
||||
|
||||
/**
|
||||
* The priority by which this token gets sorted.
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.nwapw.abacus.tree
|
||||
|
||||
/**
|
||||
* A tree node that represents a binary tree value operator.
|
||||
*
|
||||
*
|
||||
* The tree value operators operate on trees, and so this
|
||||
* node does not reduce its children. It is up to the implementation to handle
|
||||
* reduction.
|
||||
* @param operation the operation this node performs.
|
||||
* @param left the left child of this node.
|
||||
* @param right the right child of this node.
|
||||
*/
|
||||
class TreeValueBinaryNode(operation: String, left: TreeNode?, right: TreeNode?)
|
||||
: BinaryNode(operation, left, right) {
|
||||
|
||||
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
||||
return reducer.reduceNode(this)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.nwapw.abacus.tree
|
||||
|
||||
/**
|
||||
* A tree node that represents a unary tree value operator.
|
||||
*
|
||||
* The tree value operators operate on trees, and so this
|
||||
* node does not reduce its children. It is up to the implementation to handle
|
||||
* reduction.
|
||||
* @param operation the operation this node performs.
|
||||
* @param child the node the operation should be applied to.
|
||||
*/
|
||||
class TreeValueUnaryNode(operation: String, child: TreeNode?)
|
||||
: UnaryNode(operation, child) {
|
||||
|
||||
override fun <T : Any> reduce(reducer: Reducer<T>): T? {
|
||||
return reducer.reduceNode(this);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user