do precedence better

This commit is contained in:
dfsek
2020-12-31 02:03:47 -07:00
parent 92afe1c9ab
commit ad5823055d
3 changed files with 32 additions and 2 deletions

View File

@@ -286,7 +286,7 @@ public class Parser {
Returnable<?> right = parseExpression(tokens, false, variableMap);
Token other = tokens.get();
if(other.isBinaryOperator() && (other.getType().equals(Token.Type.MULTIPLICATION_OPERATOR) || other.getType().equals(Token.Type.DIVISION_OPERATOR))) {
if(ParserUtil.hasPrecedence(binaryOperator.getType(), other.getType())) {
return assemble(left, parseBinaryOperation(right, tokens, variableMap), binaryOperator);
} else if(other.isBinaryOperator()) {
return parseBinaryOperation(assemble(left, right, binaryOperator), tokens, variableMap);

View File

@@ -5,8 +5,26 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.tokenizer.Token;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ParserUtil {
private static final Map<Token.Type, List<Token.Type>> PRECEDENCE = new HashMap<>();
private static final List<Token.Type> ARITHMETIC = Arrays.asList(Token.Type.ADDITION_OPERATOR, Token.Type.SUBTRACTION_OPERATOR, Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR);
static { // Setup precedence
PRECEDENCE.put(Token.Type.ADDITION_OPERATOR, Arrays.asList(Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR));
PRECEDENCE.put(Token.Type.SUBTRACTION_OPERATOR, Arrays.asList(Token.Type.MULTIPLICATION_OPERATOR, Token.Type.DIVISION_OPERATOR));
PRECEDENCE.put(Token.Type.EQUALS_OPERATOR, ARITHMETIC);
PRECEDENCE.put(Token.Type.NOT_EQUALS_OPERATOR, ARITHMETIC);
PRECEDENCE.put(Token.Type.GREATER_THAN_OPERATOR, ARITHMETIC);
PRECEDENCE.put(Token.Type.GREATER_THAN_OR_EQUALS_OPERATOR, ARITHMETIC);
PRECEDENCE.put(Token.Type.LESS_THAN_OPERATOR, ARITHMETIC);
PRECEDENCE.put(Token.Type.LESS_THAN_OR_EQUALS_OPERATOR, ARITHMETIC);
}
public static void checkType(Token token, Token.Type... expected) throws ParseException {
for(Token.Type type : expected) if(token.getType().equals(type)) return;
throw new ParseException("Expected " + Arrays.toString(expected) + " but found " + token.getType(), token.getPosition());
@@ -59,4 +77,9 @@ public class ParserUtil {
throw new ParseException("Unexpected token " + varToken.getType() + "; expected variable declaration", varToken.getPosition());
}
}
public static boolean hasPrecedence(Token.Type first, Token.Type second) {
if(!PRECEDENCE.containsKey(first)) return false;
return PRECEDENCE.get(first).contains(second);
}
}

View File

@@ -7,6 +7,11 @@ num testVar = 3.4;
bool boolean = true;
str stringVar = "hello!";
num precedence = 2 + 2 * 2;
test("precedence: " + precedence, 2);
num precedence2 = 2 * 2 + 2;
test("precedence 2: " + precedence2, 2);
bool iftest = false;
bool truetest = false;
@@ -19,7 +24,9 @@ for(num i = 0; i < 5; i = i + 1) {
for(num j = 0; j < 5; j = j + 1) test("single statement j = " + j, iterator);
if(4 + 2 == 2 + 4) {
test("new thing " + 2, iterator);
}
while(iterator < 5) {
test("always, even after " + 2, iterator);