Skip to content

Instantly share code, notes, and snippets.

@pinglunliao
Last active November 5, 2019 08:33
Show Gist options
  • Save pinglunliao/bf28c7d903d5606b3a43 to your computer and use it in GitHub Desktop.
Save pinglunliao/bf28c7d903d5606b3a43 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <string>
using namespace std;
void eatspaces(string &str); // Function to eliminate blanks
int expr(string &str); // Function evaluating an expression
int term(string &str, int& index); // Function analyzing a term
int number(string &str, int& index); // Function to recognize a number
string extract(string &str, int& index); //Function to extract a substring
int main(void)
{
string buffer; // Input area for expression to be evaluated
while( getline(cin, buffer) )
{
eatspaces(buffer); // Remove blanks from input
cout << expr(buffer) // Output value of expression
<< endl;
//cout << buffer << endl;
}
}
// Function to eliminate blanks from a string
void eatspaces(string &str)
{
for(unsigned i = 0; i < str.length(); i++)
{
if(str[i] == ' ')
str.erase(i, 1);
}
}
// Function to evaluate an arithmetic expression
int expr(string &str)
{
int value = 0; // Store result here
int index = 0; // Keeps track of current character position
value = term(str, index); // Get first term
for(;;) // Infinite loop, all exits inside
{
switch(str[index++]) // Choose action based on current character
{
case '\0': // We're at the end of the string
return value; // so return what we have got
case '+': // + found so add in the
value += term(str, index); // next term
break;
case '-': // - found so subtract
value -= term(str, index); // the next term
break;
default: // If we reach here the string
cout << endl // is junk
<< "Arrrgh!*#!! There's an error"
<< endl;
exit(1);
}
}
}
// Function to get the value of a term
int term(string &str, int& index)
{
int value = 0; // Somewhere to accumulate the result
value = number(str, index); // Get the first number in the term
// Loop as long as we have a good operator
while( (str[index]=='*') || (str[index]=='/') || (str[index]=='%') )
{
if(str[index]=='*') // If it's multiply,
value *= number(str, ++index); // multiply by next number
if(str[index]=='/') // If it's divide,
value /= number(str, ++index); // divide by next number
if(str[index]=='%')
value = value % number(str, ++index);
}
return value; // We've finished, so return what we've got
}
// Function to recognize an expression in parentheses
// or a number in a string
int number(string &str, int& index)
{
int value = 0; // Store the resulting value
if(str[index] == '(') // Start of parentheses
{
string psubstr; // Pointer for substring
psubstr = extract(str, ++index); // Extract substring in brackets
//cout << "psubstr: " << psubstr << endl;
value = expr(psubstr); // Get the value of the substring
return value; // Return substring value
}
//cout << "number value: " << value << endl;
while(isdigit(str[index])) // Loop accumulating leading digits
value=10*value + ((str[index++]) - 48);
// Not a digit when we get to here
return value; // On loop exit we are done
}
// Function to extract a substring between parentheses
// (requires string)
string extract(string &str, int& index)
{
string pstr; // Pointer to new string for return
int numL = 0; // Count of left parentheses found
int bufindex = index; // Save starting value for index
do
{
switch(str[index])
{
case ')':
if(numL==0)
{
++index;
pstr = str.substr(bufindex, index - bufindex-1);
//str.erase(bufindex - 1, index - bufindex + 1);
//cout << "extract pstr: " << pstr << endl;
//cout << "str: " << str << endl;
return pstr; // Return substring in new memory
}
else
numL--; // Reduce count of '(' to be matched
break;
case '(':
numL++; // Increase count of '(' to be matched
break;
}
} while(index++ < str.length());// Loop - don't overrun end of string
cout << "Ran off the end of the expression, must be bad input."
<< endl;
exit(1);
return pstr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment