[poincare] Correct stoppingType for parseSlash

This commit is contained in:
Ruben Dashyan
2018-10-03 14:06:10 +02:00
committed by Émilie Feral
parent 20a1e048de
commit c1943cfb49
2 changed files with 40 additions and 17 deletions

View File

@@ -37,8 +37,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) {
do {
int parserIndex = static_cast<int>(m_currentToken.type());
leftHandSide = (this->*(tokenParsers[parserIndex]))(leftHandSide);
} while (canPopToken(stoppingType));
assert(!leftHandSide.isUninitialized());
} while (!leftHandSide.isUninitialized() && canPopToken(stoppingType));
return leftHandSide;
}
@@ -70,36 +69,41 @@ Expression Parser::parseNumber(Expression leftHandSide) {
}
Expression Parser::parsePlus(Expression leftHandSide) {
assert(!leftHandSide.isUninitialized());
return Addition(leftHandSide, parseUntil(Token::Type::Plus)); // Addition is left-associative.
return parseBinaryOperator<Addition>(leftHandSide, Token::Type::Plus);
}
Expression Parser::parseTimes(Expression leftHandSide) {
assert(!leftHandSide.isUninitialized());
return Multiplication(leftHandSide, parseUntil(Token::Type::Times)); // Multiplication is left-associative.
return parseBinaryOperator<Multiplication>(leftHandSide, Token::Type::Times); // Multiplication is left-associative.
}
Expression Parser::parseSlash(Expression leftHandSide) {
assert(!leftHandSide.isUninitialized());
return Division(leftHandSide, parseUntil(Token::Type::Power)); // Division is left-associative.
return parseBinaryOperator<Division>(leftHandSide, Token::Type::Slash);
}
Expression Parser::parseMinus(Expression leftHandSide) {
if (leftHandSide.isUninitialized()) {
return Opposite(parseUntil(Token::Type::Slash));
} else {
return Subtraction(leftHandSide, parseUntil(Token::Type::Minus)); // Subtraction is left-associative.
Expression rightHandSide = parseUntil(Token::Type::Minus); // Subtraction is left-associative
if (rightHandSide.isUninitialized()) {
return Expression();
}
return Subtraction(leftHandSide, rightHandSide);
}
}
Expression Parser::parsePower(Expression leftHandSide) {
assert(!leftHandSide.isUninitialized());
return Power(leftHandSide, parseUntil(Token::Type::Slash)); // Power is right-associative
return parseBinaryOperator<Power>(leftHandSide, Token::Type::Slash); // Power is right-associative
}
Expression Parser::parseLeftParenthesis(Expression leftHandSide) {
assert(leftHandSide.isUninitialized());
Expression rightHandSide = parseUntil(Token::Type::RightParenthesis);
if (!expect(Token::Type::RightParenthesis)) {
return Expression();
}
return Parenthesis(rightHandSide);
}

View File

@@ -32,6 +32,20 @@ public:
m_currentToken(Token(Token::Type::Undefined)),
m_nextToken(m_tokenizer.popToken()) {}
Expression parse();
private:
void popToken() {
m_currentToken = m_nextToken;
m_nextToken = m_tokenizer.popToken();
}
bool expect(Token::Type type) {
popToken();
return m_currentToken.type() == type;
}
bool canPopToken(Token::Type stoppingType);
Expression parseUntil(Token::Type stoppingType);
Expression parseNumber(Expression leftHandSide);
Expression parsePlus(Expression leftHandSide);
@@ -44,13 +58,18 @@ public:
Expression parseBang(Expression leftHandSide);
Expression parseEqual(Expression leftHandSide);
Expression noParse(Expression leftHandSide);
private:
Expression parseUntil(Token::Type stoppingType);
void popToken() {
m_currentToken = m_nextToken;
m_nextToken = m_tokenizer.popToken();
template <class T>
Expression parseBinaryOperator(Expression leftHandSide, Token::Type type) {
if (leftHandSide.isUninitialized()) {
return Expression();
}
Expression rightHandSide = parseUntil(type);
if (rightHandSide.isUninitialized()) {
return Expression();
}
return T(leftHandSide, rightHandSide);
}
bool canPopToken(Token::Type stoppingType);
Tokenizer m_tokenizer;
Token m_currentToken;