From c1943cfb49b9bb467707d3f03723e0df164c847e Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 3 Oct 2018 14:06:10 +0200 Subject: [PATCH] [poincare] Correct stoppingType for parseSlash --- poincare/src/parsing/parser.cpp | 26 +++++++++++++++----------- poincare/src/parsing/parser.h | 31 +++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index 8dc73f120..a8c085de6 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -37,8 +37,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) { do { int parserIndex = static_cast(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(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(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(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(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); } diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h index e84f2dba1..04d5e2c2a 100644 --- a/poincare/src/parsing/parser.h +++ b/poincare/src/parsing/parser.h @@ -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 + 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;