polish.cpp

来自「数据结构与程序设计教材源码 数据结构与程序设计教材源码」· C++ 代码 · 共 236 行

CPP
236
字号
int Token::priority()
{

   if (kind() == operand) return -1;
   if (kind() == leftparen) return -1;
   if (kind() == rightparen) return -1;
   if (kind() == end_expression) return -1;
   switch (value[0]) {
   case '+': return 4;
   case '-': return 4;
   case '*': return 5;
   case '/': return 5;
   case '%': return 5;
   case '~': return 6;
   }
   return -1;
}
 
Value get_value(Token &t)
{
   Value answer = 0;
   char *p = t.value;
   while (*p != 0) answer = 10 * answer + *(p++) - '0';
   return answer;
}
 
Value do_binary(Token &t, Value &x, Value &y)
{
   switch (t.value[0]) {
   case '+': return x + y;
   case '-': return x - y;
   case '*': return x * y;
   case '/': return x / y;
   case '%': return x % y;
   }
   return x;
}
 
Value do_unary(Token &t, Value &x)
{
   if (t.value[0] == '-') return -x;
   return x;
}
 
#include "../../4/NODES/NODE.CPP"
#include "../../4/LINKSTAC/STACK.CPP"
 
Expression Expression::infix_to_postfix()
/* 
 
Pre:   The Expression stores a valid infix expression.
Post: A postfix expression that translates the infix expression is returned.
 
*/
 
{
   Expression answer;
   Token current, prior;
   Stack delayed_operations;

   while (get_token(current) != fail) {
      switch (current.kind()) {
      case operand:
         answer.put_token(current);
         break;

      case leftparen:
         delayed_operations.push(current);
         break;

      case rightparen:
         delayed_operations.top(prior);
         while (prior.kind() != leftparen) {
            answer.put_token(prior);
            delayed_operations.pop();
            delayed_operations.top(prior);
         }
         delayed_operations.pop();
         break;

      case unaryop:
      case binaryop:               //  Treat all operators together.
         bool end_right = false;   //  End of right operand reached?

         do {
            if (delayed_operations.empty()) end_right = true;
            else {
               delayed_operations.top(prior);
               if (prior.kind() == leftparen) end_right = true;
               else if (prior.priority() < current.priority()) end_right = true;
               else if (current.priority() == 6) end_right = true;
               else answer.put_token(prior);
               if (!end_right) delayed_operations.pop();
            }
         } while (!end_right);

         delayed_operations.push(current);
         break;
      }
   }
   while (!delayed_operations.empty()) {
      delayed_operations.top(prior);
      answer.put_token(prior);
      delayed_operations.pop();
   }
   answer.put_token(";");
   return answer;
}
 
Error_code Expression::recursive_evaluate(Value &result, Token &final)
{
   while (true) {
      if (get_token(final) == fail) return fail;
      switch (final.kind()) {
      case binaryop:
      case end_expression:
         return success;

      case rightunaryop:
      case unaryop:
         result = do_unary(final, result);
         break;

      case operand:
         Value second_arg = get_value(final);
         if (recursive_evaluate(second_arg, final) == fail) return fail;
         if (final.kind() != binaryop) return fail;
         result = do_binary(final, result, second_arg);
         break;
      }
   }
}
 

Error_code Expression::evaluate_postfix(Value &result)
{
   Token t;
   Error_code outcome;
   if (get_token(t) == fail || t.kind() != operand) outcome = fail;
   else {
      result = get_value(t);
      outcome = recursive_evaluate(result, t);
      if (outcome == success && t.kind() != end_expression)
         outcome = fail;
   }
   return outcome;
}
 
Error_code Expression::evaluate_prefix(Value &result)
{
   Token t;
   Value x, y;
   if (get_token(t) == fail) return fail;
   switch (t.kind()) {
   case unaryop:
      if (evaluate_prefix(x) == fail) return fail;
      else result = do_unary(t, x);
      break;

   case binaryop:
      if (evaluate_prefix(x) == fail) return fail;
      if (evaluate_prefix(y) == fail) return fail;
      else result = do_binary(t, x, y);
      break;

   case operand:
      result = get_value(t);
      break;
   }
   return success;
}
 
Token_type Token::kind()
{
   if ('0' <= value[0] && value[0] <= '9') return operand;
   if (value[0] == '-' && value[1] != 0) return operand;
   if (value[0] == '~') return unaryop;
   if (value[0] == '+') return binaryop;
   if (value[0] == '-') return binaryop;
   if (value[0] == '*') return binaryop;
   if (value[0] == '/') return binaryop;
   if (value[0] == '%') return binaryop;
   if (value[0] == '(') return leftparen;
   if (value[0] == ')') return rightparen;
   else return end_expression;
}
 
void Expression::put_token(char *result) {
   strcat(value, result);
   strcat(value, " ");
   count += 1 + strlen(result);
}
 
void Expression::put_token(Token &result) {
   strcat(value, result.value);
   strcat(value, " ");
   count += 1 + strlen(result.value);
}
 
Error_code Expression::get_token(Token &result) {
   while (start < count) {
      char c = value[start];
      if ('0' <= c && c <= '9') {
         int i = 0;
         char *p = result.value;
         p[i] = c;
         while ('0' <= (c = value[++start]) && c <= '9')
            if (i < 18) p[++i] = c;
         if (i < 19) p[++i] = '\0';
         else p[19] = '\0';
         return success;
      }

      else if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%' || c == '~'
         || c == ';' || c == '(' || c == ')') {
         start++;
         char *p = result.value;
         p[0] = c; p[1] = '\0';
         return success;
      }
      else start++;
   }
   return fail;
}
 
void Expression::read()
{
   clear();
   while (1) {
      char c;
      c = value[count++] = cin.get();
      if (c == '$') break;
   }
   value[count] = '\0';
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?