Title Description Description
The expression that we write usually is called infix expression, because it puts the operator in the middle of two operands, in many cases, in order to determine the order of operations, the parentheses are not limited, and infix expressions do not have to use parentheses.
Suffix notation: When writing an expression, the operation is immediately followed by an operation of two operands, so that the processing and precedence of the computer are handled without parentheses, simplifying the processing rules of the machine to: from left to right in order to complete the calculation and replace it with the result.
For example: 8– (3+2*6)/5+4 can be written as: 8 3 2 6*+5/–4+
The calculation steps are: 8 3 2 6 * + 5/–4 +
8 3 12 + 5/–4 +
8 15 5/–4 +
8 3–4 +
5 4 +
9
Write a program that completes the conversion and requires a space between each data in the output. Enter a description input Description
The line is a suffix expression. Only these basic symbols, "0123456789+-*/^ ()", are entered in the symbol and do not appear in the form of 2*-3.
The basic numbers in the expression are also one and do not appear as a number in the form of 12.
Do not mistake the string you entered. Outputs description Output Description
A number of the prefix expressions, the i+1 line is less than line I an operator and an operand, and the last row has only one number that represents the result of the operation.
The result of the operation may be a negative number, "/" to divide the operation. Sample input to sample
8– (3+2*6)/5+4 sample output
8 3 2 6 * + 5/–4 +
8 3 12 + 5/–4 +
8 15 5/–4 +
8 3–4 +
5 4 +
9
Analysis: This topic exercises some content of compiling principle. Including recursive descent algorithm, the elimination of left recursion, grammar-guided translation of a small part of the content.
The recursive descent is converted to a suffix, and then the expression is computed by the suffix method, and each time a result is computed, the entire suffix is output once.
The expression required in the topic eliminates the left recursion after.
E->t1e1
e1->+t1e1 | -t1e1
T1->t2t11
t11->*t2t11 | /t2t11
t2->t3t22
t22->^t3t22
T3-> (E) | I
And then the code is easy, and the codes are as follows. You should ensure that the input is correct for this topic, so there is no hint of error.
#include <iostream> #include <list> #include <string> #include <cmath> using namespace std; String str; sentence int i = 0;
The position of the read-in character list<char> PostFix;
void T ();
void E1 ();
void T1 ();
void T11 ();
void T2 ();
void T22 ();
void T3 ();
void G ();
void F ();
void S ();
void E () {T1 ();
E1 ();
} void E1 () {if (I < str.size () && (str[i] = = ' + ' | | str[i] = = '-')) {int ti = i;
i++;
T1 ();
if (str[ti] = = ' + ') {postfix.push_back (' + ');
} else {postfix.push_back ('-');
} E1 ();
}} void T1 () {T2 ();
T11 ();
} void T11 () {if (I < str.size () && (str[i] = = ' * ' | | str[i] = = '/')) {int ti = i;
i++;
T2 ();
if (str[ti] = = ' * ') {postfix.push_back (' * ');
} else if (str[ti] = = '/') {postfix.push_back ('/');
} T11 ();
}} void T2 () {T3 ();
T22 ();
} void T22 () {if (I < str.size () && str[i] = = ' ^ ') {i++;
T3 ();
Postfix.push_back (' ^ ');
T22 (); }} void T3 ()//terminator or () {if (ISAlnum (Str[i]) {postfix.push_back (str[i]);
i++;
} else if (str[i] = = ' (') {i++;
E ();
if (str[i] = = ') ') {i++;
}}} void print (List<int> &operand) {List<int>::iterator it;
for (List<int>::iterator it = Operand.begin (); It! = Operand.end (); ++it) {cout<<*it<< "";
} for (List<char>::iterator it = Postfix.begin (); It! = Postfix.end (); ++it) {cout<<*it<< "";
} cout<<endl;
} void Cal ()//expression is left-to-right combined with {list<int> operand;
print (operand);
For (;p ostfix.size () > 0;)
{if (Isalnum (Postfix.front ())) {Operand.push_back (Postfix.front ()-' 0 ');
Postfix.pop_front ();
} else {char c = postfix.front ();
Postfix.pop_front ();
int n1 = Operand.back ();
Operand.pop_back ();
int n2 = Operand.back ();
Operand.pop_back ();
Switch (c) {case '-': Operand.push_back (N2-N1);
Break
Case ' + ': Operand.push_back (N2+N1);
Break Case ' * ': Operand.push_back (N2*N1);
Break
Case '/': Operand.push_back (N2/N1);
Break
Case ' ^ ': operand.push_back ((int) POW (n2*1.0,n1*1.0));
Break
} print (operand);
}}} int main () {cin >> str;
E ();
Cal ();
return 0; }
Some references:
[1]http://wenku.baidu.com/view/2ae7e28fcc22bcd126ff0c08.html
Compilation principle 6-4.2-4.3-top-down translation-recursive descent translation
[2]http://blog.sina.com.cn/s/blog_687911280100nc8t.html
Left recursive elimination.
[3]http://wenku.baidu.com/view/c3c9255f804d2b160b4ec0e7.html?re=view
Recursive descent translation
[4]http://wenku.baidu.com/view/cb7d67631ed9ad51f01df254.html?re=view
The sixth chapter attribute grammar and grammatical guidance translation
[5]http://blog.csdn.net/chosen0ne/article/category/1247484
This article defines the arithmetic priority.