Поддержка операций сравнения

This commit is contained in:
Victor 2015-04-16 17:33:09 +03:00
parent d7c85173b1
commit f3d4930cec
4 changed files with 47 additions and 14 deletions

View File

@ -15,10 +15,11 @@ public final class Lexer {
return new Lexer().process(input).getTokens(); return new Lexer().process(input).getTokens();
} }
private static final String OPERATOR_CHARS = "=+-()[]!$:"; private static final String OPERATOR_CHARS = "=+-<>()[]!$:";
private static final TokenType[] OPERATOR_TYPES = new TokenType[] { private static final TokenType[] OPERATOR_TYPES = new TokenType[] {
TokenType.EQ, TokenType.EQ,
TokenType.PLUS, TokenType.MINUS, TokenType.PLUS, TokenType.MINUS,
TokenType.LT, TokenType.GT,
TokenType.LPAREN, TokenType.RPAREN, TokenType.LBRACKET, TokenType.RBRACKET, TokenType.LPAREN, TokenType.RPAREN, TokenType.LBRACKET, TokenType.RBRACKET,
TokenType.EXCL, TokenType.COMMAND, TokenType.COLON, TokenType.EXCL, TokenType.COMMAND, TokenType.COLON,
}; };

View File

@ -447,25 +447,50 @@ public final class Parser {
if (match(TokenType.NOT)) { if (match(TokenType.NOT)) {
return new ValueExpression( notTest().eval() != 0 ? 0 : 1 ); return new ValueExpression( notTest().eval() != 0 ? 0 : 1 );
} }
return equality(); return comparison();
} }
private Expression equality() { private Expression comparison() {
Expression expression = additive(); Expression expression = additive();
if (lookMatch(1, TokenType.EQ)) { while (true) {
if (match(TokenType.EQ)) { if (lookMatch(1, TokenType.EQ)) {
// == if (match(TokenType.EQ)) {
match(TokenType.EQ); // ==
return new BinaryExpression(Operator.EQUALS, expression, additive()); match(TokenType.EQ);
expression = new BinaryExpression(Operator.EQUALS, expression, additive());
continue;
}
if (match(TokenType.GT)) {
// >=
match(TokenType.EQ);
expression = new BinaryExpression(Operator.GTEQ, expression, additive());
continue;
}
if (match(TokenType.LT)) {
// <=
match(TokenType.EQ);
expression = new BinaryExpression(Operator.LTEQ, expression, additive());
continue;
}
if (match(TokenType.EXCL)) {
// !=
match(TokenType.EQ);
expression = new BinaryExpression(Operator.NOTEQUALS, expression, additive());
continue;
}
} }
if (match(TokenType.EXCL)) {
// != if (match(TokenType.LT)) {
match(TokenType.EQ); expression = new BinaryExpression(Operator.LT, expression, additive());
return new BinaryExpression(Operator.NOTEQUALS, expression, additive()); continue;
} }
if (match(TokenType.GT)) {
expression = new BinaryExpression(Operator.GT, expression, additive());
continue;
}
break;
} }
return expression; return expression;
} }

View File

@ -14,6 +14,8 @@ public enum TokenType {
EQ, EQ,
PLUS, PLUS,
MINUS, MINUS,
LT,
GT,
LPAREN, LPAREN,
RPAREN, RPAREN,
LBRACKET, LBRACKET,

View File

@ -9,6 +9,7 @@ public class BinaryExpression implements Expression {
ADD, SUBTRACT, ADD, SUBTRACT,
BOOLEAN_OR, BOOLEAN_AND, BOOLEAN_OR, BOOLEAN_AND,
EQUALS, NOTEQUALS, EQUALS, NOTEQUALS,
GT, GTEQ, LT, LTEQ
} }
public final Operator operator; public final Operator operator;
@ -31,6 +32,10 @@ public class BinaryExpression implements Expression {
case NOTEQUALS: return (leftVal != rightVal) ? 1 : 0; case NOTEQUALS: return (leftVal != rightVal) ? 1 : 0;
case BOOLEAN_OR: return ((leftVal != 0) || (rightVal != 0)) ? 1 : 0; case BOOLEAN_OR: return ((leftVal != 0) || (rightVal != 0)) ? 1 : 0;
case BOOLEAN_AND: return ((leftVal != 0) && (rightVal != 0)) ? 1 : 0; case BOOLEAN_AND: return ((leftVal != 0) && (rightVal != 0)) ? 1 : 0;
case GT: return (leftVal > rightVal) ? 1 : 0;
case LT: return (leftVal < rightVal) ? 1 : 0;
case GTEQ: return (leftVal >= rightVal) ? 1 : 0;
case LTEQ: return (leftVal <= rightVal) ? 1 : 0;
default: default:
throw new RuntimeException("Неизвестный оператор " + operator.name()); throw new RuntimeException("Неизвестный оператор " + operator.name());
} }