Demonstration 1
input infix
was+2 +33
output suffix
was 2 + 33 +
Demonstration 2
infix
((1+3)*2 + 5)*33
suffix
1 3 + 2 * 5 + 33 *
train of thought
I'll perfect it when I have time. The whole is inspired by the compilation principle textbook. The key is to write left-recursive productions, and then eliminate left-recursion, expressing it in a way that is easy to implement with programs.
the code
/* 左递归
expr -> expr + term {print(‘+’)}
| expr - term {print(‘-’)}
| term
term -> term * factor {print(‘*’)}
| term / factor {print(‘/’)}
| factor
factor -> (expr)
| id { print(lexeme) }
| num { print(tokenval) }
-----------------------------------------------------
消除左递归后
expr -> term rest
rest -> + term print{('+')} rest
| - term print{('-')} rest
| 空
term -> factor rest2
rest2 -> * factor print{('*')} rest2
| / factor print{('/')} rest2
| 空
factor -> (expr)
| id {print(id)}
| num {print(num)
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
using namespace std;
#define TKN_NUM 500
#define TKN_ID 600
int LookAhead; //词法单元类型
char lexeme[1000];//词素
int tokenval = 0; //记录完整的数值
int getToken();
void Match(int i);
void factor();
void rest2();
void term();
void rest();
void expr();
int getToken(){
int i, t;
while(1){
t = getchar();
if(t == ' ' || t == '\t')
;
else if(isdigit(t)){
tokenval = 0;
do {
tokenval = tokenval * 10 + t -'0';
t = getchar();
} while (isdigit(t));
ungetc(t, stdin); //把字符 char(一个无符号字符)推入到指定的流 stream 中,以便它是下一个被读取到的字符。即回退
return TKN_NUM;
}
else if(isalpha(t)){
i = 0;
do {
lexeme[i++]=t;
t = getchar();
}while( isalpha(t) || isdigit(t) );
lexeme[i]='\0';
ungetc(t, stdin);//回退
return TKN_ID;
}
else{
tokenval = 0;
return t; //+ - * / ( ).etc
}
}
}
void Match(int i){
if(i == LookAhead){
LookAhead = getToken();
}
else{
printf("\nmatch error\n", i);
exit(1);
}
}
void factor(){
if( LookAhead==TKN_NUM) {
printf("%d ",tokenval);
Match(LookAhead);
}
else if( LookAhead==TKN_ID) {
printf("%s ",lexeme);
Match(LookAhead);
}
else if( LookAhead == '('){
//stack_.push_back('(');
LookAhead = getToken();
expr();
if(LookAhead != ')'){
printf("\nBracket mismatch\n" );
exit(1); //结束程序
}
LookAhead = getToken();
}
else{
printf("\nerror\n" );
exit(1); //结束程序
}
}
void rest2(){
switch( LookAhead ) {
case '*':
Match('*');
factor();
printf("* ");
rest2(); // rest --> + term {print('+')} rest
break;
case '/':
Match('/');
factor();
printf("/ ");
rest2(); // rest --> - term {print('-')} rest
break;
default: // rest --> 空
break;
}
}
void term(){
factor();
rest2();
}
void rest(){
switch(LookAhead){
case '+':
Match('+');
term();
printf("+ ");
rest();
break;
case '-':
Match('-');
term();
printf("- ");
rest();
default:
break;
}
}
void expr(){
term();
rest();
}
int main(){
printf("Input inOrder expression:\n");
LookAhead = getToken();
printf("postOrder is:\n");
expr();
return 0;
}
test