#include<iostream>
#include<string>
using std::cin;
using std::cout;
using std::endl;
using std::string;
#define # -1
#define ERROR -2
#define variable 1
#define integer 2
#define decimal 3
#define plus 4
#define minus 5
#define multiply 6
#define divide 7
#define LP 8
#define RP 9
struct Tree
{
int type = 0;
string detail;
Tree *lchild = nullptr;
Tree *rchild = nullptr;
};
#include "data.h"
FILE * file;
string curtoken;
int curtokenType;
string nexttoken;
int nexttokenType;
bool right=true;
void getToken();
Tree* getExpression();
Tree* getTerm();
Tree* getFactor();
void traversal(Tree *root,int &i,int &j)//只能后序
{
if (root)
{
if (!root->lchild&&!root->rchild)//如果该结点是叶子结点
{
cout << root->detail;
}
//如果左孩子是叶子,右孩子不是
else if (!root->lchild->lchild&&!root->lchild->rchild&&root->rchild->lchild&&root->rchild->rchild)
{
traversal(root->rchild, i,j);
traversal(root->lchild, i,j);
cout << ' ';
cout << '(' << ++i << ')';
cout << ' ';
cout << root->detail;
cout << "\t---->(" << ++j << ")"<<endl;
}
else
{
traversal(root->lchild,i,j);
cout << ' ';
traversal(root->rchild, i,j);
if (root->lchild->type == 4 || root->lchild->type == 5 || root->lchild->type == 6 || root->lchild->type == 7)
{
cout << '(' << ++i << ')';
}
cout << ' ';
if (root->rchild->type == 4 || root->rchild->type == 5 || root->rchild->type == 6 || root->rchild->type == 7)
{
cout << '(' << ++i << ')'<<' ';
}
cout << ' ';
cout << root->detail;
cout << "\t---->(" << ++j << ")" << endl;
}
}
}
int main()
{
char buffer[256]="C:\\Users\\Administrator\\Desktop\\parser\\parser\\input.txt";
//scanf_s("%s", buffer,255);
int errno_terr;
if (errno_terr = fopen_s(&file, buffer, "r"))
{
printf("n打开源程序文件出错!n");
return -1;
}
getToken();
auto root=getExpression();
int i=0,j=0;
if (right)
{
traversal(root, i, j);
}
else
{
cout << "四则运算式有错" << endl;
}
fclose(file);
getchar();
return 0;
}
#include "data.h"
extern FILE * file;
extern string curtoken;
extern int curtokenType;
extern string nexttoken;
extern int nexttokenType;
void getToken()//词法分析函数:每次调用,可以得到下一个非字符型单词的具体内容以及类型
{
curtoken = nexttoken;
curtokenType = nexttokenType;
//初始化单词类型以及容器
nexttoken.clear();
nexttokenType = #;
char ch = getc(file);
if (ch != EOF)
{
while (ch == ' ' || ch == '\n' || ch == '\t') ch = getc(file); //跳过所有的分隔符
if (ch == EOF) return; //文件结束
if (isalpha(ch)) //如果是字母,则进行标识符处理
{
nexttoken += ch;
ch = getc(file);
while (isalnum(ch)) //如果是字母或数字组合继续;如果不是则标识符组合结束
{
nexttoken += ch; //组合的标识符保存在token中
ch = getc(file); //读下一个字符
}
nexttokenType = variable;
if (ch != EOF) fseek(file, -1, 1); //回退一个字符
}
else if (isdigit(ch))//数字处理
{
nexttoken += ch;
ch = getc(file); //读下一个字符
while (isdigit(ch)) //如果是数字则组合整数;如果不是则整数组合结束
{
nexttoken += ch; //组合整数保存在token中
ch = getc(file); //读下一个字符
}
if (ch != '.')
{
nexttokenType = integer;
}
else
{
nexttokenType = decimal;
nexttoken += '.';
ch = getc(file);
while (isdigit(ch))
{
nexttoken += ch;
ch = getc(file);
}
}
if (ch != EOF) fseek(file, -1, 1); //回退一个字符
}
else if (ch == '+')
{
nexttoken = "+";
nexttokenType = plus;
}
else if (ch == '-')
{
nexttoken = "-";
nexttokenType = minus;
}
else if (ch == '*')
{
nexttoken = "*";
nexttokenType = multiply;
}
else if (ch == '/')
{
nexttoken = "/";
nexttokenType = divide;
}
else if (ch == '(')
{
nexttoken = "(";
nexttokenType = LP;
}
else if (ch == ')')
{
nexttoken = ")";
nexttokenType = RP;
}
else
{
nexttokenType = ERROR;
}
}
}
#include "data.h"
extern string curtoken;
extern int curtokenType;
extern string nexttoken;
extern int nexttokenType;
extern bool right;
extern void getToken();
extern Tree* getExpression();
extern Tree* getTerm();
extern Tree* getFactor();
Tree *getExpression()
{
auto lchild=getTerm();
while (nexttokenType == plus || nexttokenType == minus)
{
Tree *parent = new Tree;
if (nexttokenType == plus)
{
parent->type = plus;
parent->detail = "+";
}
else
{
parent->type = minus;
parent->detail = "-";
}
getToken();
auto rchild=getTerm();
parent->lchild = lchild;
parent->rchild = rchild;
lchild = parent;
}
if (nexttokenType == variable || nexttokenType == integer || nexttokenType == decimal)
{
cout << curtoken << "和" << nexttoken << "之前没有操作符" << endl;
getchar();
exit(0);
}
return lchild;
}
Tree* getTerm()
{
auto lchild = getFactor();
while (nexttokenType == multiply || nexttokenType == divide)
{
Tree *parent = new Tree;
if (nexttokenType == multiply)
{
parent->type = multiply;
parent->detail = "*";
}
else
{
parent->type = divide;
parent->detail = "/";
}
getToken();
auto rchild = getTerm();
parent->lchild = lchild;
parent->rchild = rchild;
lchild = parent;
}
if (nexttokenType == variable || nexttokenType == integer || nexttokenType == decimal)
{
cout << curtoken << "和" << nexttoken << "之前没有操作符" << endl;
getchar();
exit(0);
}
return lchild;
}
Tree* getFactor()
{
Tree *leaf = new Tree;
getToken();
if (curtokenType == variable)
{
leaf->type = variable;
leaf->detail = curtoken;
}
else if (curtokenType == integer)
{
leaf->type = integer;
leaf->detail = curtoken;
}
else if (curtokenType ==decimal)
{
leaf->type = decimal;
leaf->detail = curtoken;
}
else if (curtokenType == LP)
{
leaf = getExpression();
getToken();
if (curtokenType != RP)
{
cout << "没有匹配的左括号" << endl;
getchar();
exit(0);
}
}
else
{
cout << curtoken << "出错" << endl;
right = false;
}
return leaf;
}