mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare/parser] -1/2 gives - 1/2 and not -(1) / 2
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)));
|
||||
|
||||
Reference in New Issue
Block a user