Guest User

Untitled

a guest
Jul 18th, 2018
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.28 KB | None | 0 0
  1. // Public routine that performs the evaluation. Examines the postfix machine
  2. // to see if a single result is left and if so, return it; otherwise prints
  3. // error.
  4. template<class NumericType>
  5. NumericType Evaluator<NumericType>::getValue( ) {
  6.  
  7. Tokenizer<NumericType> tok( str );
  8. Token<NumericType> lastToken;
  9.  
  10. do {
  11. lastToken = tok.getToken( );
  12. processToken( lastToken );
  13. } while ( lastToken.getType( ) != EOL );
  14.  
  15. if ( postFixStack.empty( ) ) {
  16. cerr << "Missing operand!" << endl;
  17. return 0;
  18. }
  19.  
  20. NumericType theResult = postFixStack.back( );
  21. postFixStack.pop_back( );
  22. if ( !postFixStack.empty( ) )
  23. cerr << "Warning: missing operators!" << endl;
  24.  
  25. return theResult;
  26. }
  27.  
  28. // After token is read, use operator precedence parsing algorithm to process
  29. // it; missing opening parentheses are detected here.
  30. template<class NumericType>
  31. void Evaluator<NumericType>::
  32. processToken( const Token<NumericType> &lastToken ) {
  33. TokenType topOp;
  34. TokenType lastType = lastToken.getType( );
  35.  
  36. switch( lastType ) {
  37. case VALUE:
  38. postFixStack.push_back( lastToken.getValue( ) );
  39. return;
  40.  
  41. case VAR_A:
  42. postFixStack.push_back( var_a );
  43. postFixVarStack.push_back( 'a' );
  44. return;
  45.  
  46. case VAR_B:
  47. postFixStack.push_back( var_b );
  48. postFixVarStack.push_back( 'b' );
  49. return;
  50. case VAR_C:
  51. postFixStack.push_back( var_c );
  52. postFixVarStack.push_back( 'c' );
  53. return;
  54.  
  55.  
  56.  
  57. case CPAREN:
  58. while( ( topOp = opStack.back( ) ) != OPAREN &&
  59. topOp != EOL )
  60. binaryOp( topOp );
  61. if ( topOp == OPAREN )
  62. opStack.pop_back( ); // get rid of opening parethesis
  63. else
  64. cerr << "Missing open parenthesis" << endl;
  65. break;
  66.  
  67. default: // general operator case
  68. while ( PREC_TABLE[ lastType ].inputSymbol <=
  69. PREC_TABLE[ topOp = opStack.back( ) ].topOfStack )
  70. binaryOp( topOp );
  71.  
  72. if ( lastToken.getType( ) != EOL )
  73. opStack.push_back( lastType );
  74.  
  75. break;
  76. }
  77. }
  78.  
  79. // Process an operator by taking two items off the postfix stack, applying
  80. // the operator, and pushing the result.
  81. // Print error if missing closing parenthesis or division by 0.
  82. template<class NumericType>
  83. void Evaluator<NumericType>::binaryOp( TokenType topOp ) {
  84. if ( topOp == OPAREN ) {
  85. cerr << "Unbalanced parenthss" << endl;
  86. opStack.pop_back( );
  87. return;
  88. }
  89. NumericType rhs = getTop( );
  90. NumericType lhs = getTop( );
  91.  
  92. // the original operators
  93. if ( topOp == PLUS )
  94. postFixStack.push_back( lhs + rhs );
  95. else if ( topOp == MINUS )
  96. postFixStack.push_back( lhs - rhs );
  97. else if ( topOp == MULT )
  98. postFixStack.push_back( lhs * rhs );
  99. else if ( topOp == DIV )
  100. if ( rhs != 0 )
  101. postFixStack.push_back( lhs / rhs );
  102. else {
  103. cerr << "Division by zero" << endl;
  104. postFixStack.push_back( lhs );
  105. }
  106.  
  107. // C++ operators
  108. else if ( topOp == MODULUS )
  109. postFixStack.push_back( lhs % rhs );
  110. else if ( topOp == SHIFT_L )
  111. postFixStack.push_back( lhs << rhs );
  112. else if ( topOp == SHIFT_R )
  113. postFixStack.push_back( lhs >> rhs );
  114. else if ( topOp == LT )
  115. postFixStack.push_back( lhs < rhs );
  116. else if ( topOp == LE )
  117. postFixStack.push_back( lhs <= rhs );
  118. else if ( topOp == GT )
  119. postFixStack.push_back( lhs > rhs );
  120. else if ( topOp == GE )
  121. postFixStack.push_back( lhs >= rhs );
  122. else if ( topOp == EQUAL )
  123. postFixStack.push_back( lhs == rhs );
  124. else if ( topOp == NOTEQUAL )
  125. postFixStack.push_back( lhs != rhs );
  126. else if ( topOp == BIT_AND )
  127. postFixStack.push_back( lhs & rhs );
  128. else if ( topOp == BIT_EOR )
  129. postFixStack.push_back( lhs ^ rhs );
  130. else if ( topOp == BIT_IOR )
  131. postFixStack.push_back( lhs | rhs );
  132. else if ( topOp == LOG_AND )
  133. postFixStack.push_back( lhs && rhs );
  134. else if ( topOp == LOG_OR )
  135. postFixStack.push_back( lhs || rhs );
  136.  
  137. opStack.pop_back( );
  138. }
  139.  
  140. // top and pop the postfix machine stack; return the result.
  141. // If the stack is empty, print an error message.
  142. template<class NumericType>
  143. NumericType Evaluator<NumericType>::getTop( ) {
  144. if ( postFixStack.empty( ) ) {
  145. cerr << "Missing operand" << endl;
  146. return 0;
  147. }
  148.  
  149. NumericType tmp = postFixStack.back( );
  150. postFixStack.pop_back( );
  151. return tmp;
  152. }
Add Comment
Please, Sign In to add comment