[poincare/parser] -1/2 gives - 1/2 and not -(1) / 2

This commit is contained in:
Léa Saviot
2019-01-08 12:24:11 +01:00
parent 9709fb66b1
commit 4788495d62
3 changed files with 41 additions and 39 deletions

View File

@@ -2,6 +2,8 @@
namespace Poincare {
static inline Token::Type maxToken(Token::Type x, Token::Type y) { return ((int)x > (int) y ? x : y); }
constexpr const Expression::FunctionHelper * Parser::s_reservedFunctions[];
Expression Parser::parse() {
@@ -50,7 +52,7 @@ bool Parser::IsSpecialIdentifierName(const char * name, size_t nameLength) {
}
Expression Parser::parseUntil(Token::Type stoppingType) {
typedef void (Parser::*TokenParser)(Expression & leftHandSide);
typedef void (Parser::*TokenParser)(Expression & leftHandSide, Token::Type stoppingType);
static constexpr TokenParser tokenParsers[] = {
&Parser::parseUnexpected, // Token::EndOfStream
&Parser::parseStore, // Token::Store
@@ -80,7 +82,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) {
Expression leftHandSide;
do {
popToken();
(this->*(tokenParsers[m_currentToken.type()]))(leftHandSide);
(this->*(tokenParsers[m_currentToken.type()]))(leftHandSide, stoppingType);
} while (m_status == Status::Progress && nextTokenHasPrecedenceOver(stoppingType));
return leftHandSide;
}
@@ -133,11 +135,11 @@ void Parser::isThereImplicitMultiplication() {
);
}
void Parser::parseUnexpected(Expression & leftHandSide) {
void Parser::parseUnexpected(Expression & leftHandSide, Token::Type stoppingType) {
m_status = Status::Error; // Unexpected Token
}
void Parser::parseNumber(Expression & leftHandSide) {
void Parser::parseNumber(Expression & leftHandSide, Token::Type stoppingType) {
if (!leftHandSide.isUninitialized()) {
m_status = Status::Error; //FIXME
return;
@@ -150,14 +152,14 @@ void Parser::parseNumber(Expression & leftHandSide) {
isThereImplicitMultiplication();
}
void Parser::parsePlus(Expression & leftHandSide) {
void Parser::parsePlus(Expression & leftHandSide, Token::Type stoppingType) {
Expression rightHandSide;
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Plus)) {
leftHandSide = Addition(leftHandSide, rightHandSide);
}
}
void Parser::parseEmpty(Expression & leftHandSide) {
void Parser::parseEmpty(Expression & leftHandSide, Token::Type stoppingType) {
if (!leftHandSide.isUninitialized()) {
m_status = Status::Error; //FIXME
return;
@@ -165,9 +167,9 @@ void Parser::parseEmpty(Expression & leftHandSide) {
leftHandSide = EmptyExpression();
}
void Parser::parseMinus(Expression & leftHandSide) {
void Parser::parseMinus(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
Expression rightHandSide = parseUntil(Token::Slash);
Expression rightHandSide = parseUntil(maxToken(stoppingType, Token::Minus));
if (m_status != Status::Progress) {
return;
}
@@ -181,35 +183,35 @@ void Parser::parseMinus(Expression & leftHandSide) {
}
}
void Parser::parseTimes(Expression & leftHandSide) {
void Parser::parseTimes(Expression & leftHandSide, Token::Type stoppingType) {
Expression rightHandSide;
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Times)) {
leftHandSide = Multiplication(leftHandSide, rightHandSide);
}
}
void Parser::parseSlash(Expression & leftHandSide) {
void Parser::parseSlash(Expression & leftHandSide, Token::Type stoppingType) {
Expression rightHandSide;
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Slash)) {
leftHandSide = Division(leftHandSide, rightHandSide);
}
}
void Parser::parseImplicitTimes(Expression & leftHandSide) {
void Parser::parseImplicitTimes(Expression & leftHandSide, Token::Type stoppingType) {
Expression rightHandSide;
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::Slash)) {
leftHandSide = Multiplication(leftHandSide, rightHandSide);
}
}
void Parser::parseCaret(Expression & leftHandSide) {
void Parser::parseCaret(Expression & leftHandSide, Token::Type stoppingType) {
Expression rightHandSide;
if (parseBinaryOperator(leftHandSide, rightHandSide, Token::ImplicitTimes)) {
leftHandSide = Power(leftHandSide, rightHandSide);
}
}
void Parser::parseEqual(Expression & leftHandSide) {
void Parser::parseEqual(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
m_status = Status::Error; // Equal must have a left operand
return;
@@ -226,7 +228,7 @@ void Parser::parseEqual(Expression & leftHandSide) {
}
}
void Parser::parseStore(Expression & leftHandSide) {
void Parser::parseStore(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
m_status = Status::Error; // Left-hand side missing.
return;
@@ -253,7 +255,7 @@ void Parser::parseStore(Expression & leftHandSide) {
leftHandSide = Store(leftHandSide, static_cast<SymbolAbstract&>(rightHandSide));
}
void Parser::parseLeftSuperscript(Expression & leftHandSide) {
void Parser::parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
m_status = Status::Error; // Power must have a left operand
return;
@@ -286,7 +288,7 @@ bool Parser::parseBinaryOperator(const Expression & leftHandSide, Expression & r
return true;
}
void Parser::parseLeftParenthesis(Expression & leftHandSide) {
void Parser::parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppingType) {
if (!leftHandSide.isUninitialized()) {
m_status = Status::Error; //FIXME
return;
@@ -303,7 +305,7 @@ void Parser::parseLeftParenthesis(Expression & leftHandSide) {
isThereImplicitMultiplication();
}
void Parser::parseBang(Expression & leftHandSide) {
void Parser::parseBang(Expression & leftHandSide, Token::Type stoppingType) {
if (leftHandSide.isUninitialized()) {
m_status = Status::Error; // Left-hand side missing
} else {
@@ -320,7 +322,7 @@ bool Parser::currentTokenIsSpecialIdentifier() const {
return IsSpecialIdentifierName(m_currentToken.text(), m_currentToken.length());
}
void Parser::parseConstant(Expression & leftHandSide) {
void Parser::parseConstant(Expression & leftHandSide, Token::Type stoppingType) {
leftHandSide = Constant(m_currentToken.text()[0]);
isThereImplicitMultiplication();
}
@@ -432,7 +434,7 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name,
}
}
void Parser::parseIdentifier(Expression & leftHandSide) {
void Parser::parseIdentifier(Expression & leftHandSide, Token::Type stoppingType) {
if (!leftHandSide.isUninitialized()) {
m_status = Status::Error; //FIXME
return;
@@ -470,7 +472,7 @@ Expression Parser::parseFunctionParameters() {
return commaSeparatedList;
}
void Parser::parseMatrix(Expression & leftHandSide) {
void Parser::parseMatrix(Expression & leftHandSide, Token::Type stoppingType) {
if (!leftHandSide.isUninitialized()) {
m_status = Status::Error; //FIXME
return;

View File

@@ -45,23 +45,23 @@ private:
void isThereImplicitMultiplication();
// Specific Token parsers
void parseUnexpected(Expression & leftHandSide);
void parseNumber(Expression & leftHandSide);
void parseConstant(Expression & leftHandSide);
void parseIdentifier(Expression & leftHandSide);
void parseEmpty(Expression & leftHandSide);
void parseMatrix(Expression & leftHandSide);
void parseLeftParenthesis(Expression & leftHandSide);
void parseBang(Expression & leftHandSide);
void parsePlus(Expression & leftHandSide);
void parseMinus(Expression & leftHandSide);
void parseTimes(Expression & leftHandSide);
void parseSlash(Expression & leftHandSide);
void parseImplicitTimes(Expression & leftHandSide);
void parseCaret(Expression & leftHandSide);
void parseEqual(Expression & leftHandSide);
void parseStore(Expression & leftHandSide);
void parseLeftSuperscript(Expression & leftHandSide);
void parseUnexpected(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseNumber(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseConstant(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseIdentifier(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseEmpty(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseMatrix(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseBang(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parsePlus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseMinus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseTimes(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseSlash(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseImplicitTimes(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseCaret(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseEqual(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseStore(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
void parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0);
// Parsing helpers
bool parseBinaryOperator(const Expression & leftHandSide, Expression & rightHandSide, Token::Type stoppingType);

View File

@@ -161,11 +161,11 @@ QUIZ_CASE(poincare_parser_parse) {
assert_parsed_expression_is("1^2-3", Subtraction(Power(Rational(1),Rational(2)),Rational(3)));
assert_parsed_expression_is("2^-3", Power(Rational(2),Opposite(Rational(3))));
assert_parsed_expression_is("2--2+-1", Addition(Subtraction(Rational(2),Opposite(Rational(2))),Opposite(Rational(1))));
assert_parsed_expression_is("2--2*-1", Subtraction(Rational(2),Multiplication(Opposite(Rational(2)),Opposite(Rational(1)))));
assert_parsed_expression_is("2--2*-1", Subtraction(Rational(2),Opposite(Multiplication(Rational(2),Opposite(Rational(1))))));
assert_parsed_expression_is("-1^2", Opposite(Power(Rational(1),Rational(2))));
assert_parsed_expression_is("2/-3/-4", Division(Division(Rational(2),Opposite(Rational(3))),Opposite(Rational(4))));
assert_parsed_expression_is("1*2-3*4", Subtraction(Multiplication(Rational(1),Rational(2)),Multiplication(Rational(3),Rational(4))));
assert_parsed_expression_is("-1*2", Multiplication(Opposite(Rational(1)), Rational(2))); // Unary minus shall have precedence
assert_parsed_expression_is("-1*2", Opposite(Multiplication(Rational(1), Rational(2))));
assert_parsed_expression_is("1!", Factorial(Rational(1)));
assert_parsed_expression_is("1+2!", Addition(Rational(1),Factorial(Rational(2))));
assert_parsed_expression_is("1!+2", Addition(Factorial(Rational(1)),Rational(2)));