Explorar el Código

improving unary minus

Nicolas Winkler hace 5 años
padre
commit
10e9e2da30
Se han modificado 1 ficheros con 19 adiciones y 12 borrados
  1. 19 12
      libmandel/src/IterationFormula.cpp

+ 19 - 12
libmandel/src/IterationFormula.cpp

@@ -255,13 +255,13 @@ class Parser
 public:
     Parser(const std::string& s) :
         in{ s },
-        rit{ in.begin(), in.end(), tokenize }
+        rit{ in.begin(), in.end(), tokenize },
+	expectingBinaryOperator{ false }
     {}
 
     void parse(void)
     {
         std::string token;
-        bool unary = true;
         while (getToken(token)) {
             if (std::regex_match(token, num) || std::regex_match(token, floatNum)) {
                 output.push_back(mnd::Constant{ std::atof(token.c_str()) });
@@ -273,7 +273,7 @@ public:
             }
             else if (token == "+" || token == "-") {
                 if (expectingBinaryOperator) {
-                    while (!operators.empty() && getTopPrecedence() >= 1) {
+                    while (!operators.empty() && getTopPrecedence() > 3) {
                         popOperator();
                     }
                     operators.push(token[0]);
@@ -325,22 +325,29 @@ public:
             throw ParseError("error parsing expression");
         }
         char top = operators.top();
-        if (output.size() < 2) {
-            throw ParseError(std::string("not enough operands for operator '") + top + "'");
+
+        if (output.size() < 1) {
+            throw ParseError("not enough operands for unary operator '-'");
         }
-        operators.pop();
-        mnd::Expression& left = output.at(output.size() - 2);
-        mnd::Expression& right = output.at(output.size() - 1);
-        mnd::Expression newExpr = mnd::Constant{ 0.0 };
 
+
+        mnd::Expression& unaryOperand = output.at(output.size() - 1);
         // handle unary minus separately
         if (top == 'm') {
-            auto neg = mnd::Negation{ std::make_unique<mnd::Expression>(std::move(right)) };
+            auto neg = mnd::Negation{ std::make_unique<mnd::Expression>(std::move(unaryOperand)) };
             output.pop_back();
             output.push_back(std::move(neg));
             return;
         }
 
+        if (output.size() < 2) {
+            throw ParseError(std::string("not enough operands for operator '") + top + "'");
+        }
+        operators.pop();
+        mnd::Expression& left = output.at(output.size() - 2);
+        mnd::Expression& right = output.at(output.size() - 1);
+        mnd::Expression newExpr = mnd::Constant{ 0.0 };
+
         if (top == '+' || top == '-') {
             newExpr = mnd::Addition {
                 std::make_unique<mnd::Expression>(std::move(left)),
@@ -380,11 +387,11 @@ public:
 
     int getPrecedence(char op) const {
         char t = op;
-        if (t == '+' || t == '-' || t == 'm') // 'm' == unary minus
+        if (t == '+' || t == '-') // 'm' == unary minus
             return 1;
         else if (t == '*' || t == '/')
             return 2;
-        else if (t == '^')
+        else if (t == '^' || t == 'm')
             return 3;
         return 0;
     }