#include "ExprParser.h"
/*词法分析*/
int g_type,g_error,g_braBal,g_oper;
double g_value;
const char* g_str,*g_last_str,* g_pos;
int GetNextToken()
{
static char tokenBuf[32];
int tokenPos=0,nDot=0;
g_last_str=g_str;
while (*g_str==' ')++g_str; //改动1
if (!*g_str)
return g_type=END;
//Comment: Read a number!
if (isdigit(*g_str))
{
while (isdigit(*g_str)||(*g_str=='.'))
{
tokenBuf[tokenPos++] = *g_str++;
if(*g_str=='.')
nDot++;
}
tokenBuf[tokenPos]= 0;
g_value=atof((const char*)tokenBuf);
if(nDot<=1)
return g_type = NUMBER;
else
return g_type=ERROR;
}
//Comment: Read a operator.
switch (*g_str++)
{
case '+' : g_oper = ADD;return g_type=OPERATOR;
case '-' : g_oper = SUB;return g_type=OPERATOR;
case '*' : g_oper = MUL;return g_type=OPERATOR;
case '/' : g_oper = DIV;return g_type=OPERATOR;
case '(' : return g_type=LB;
case ')' : return g_type=RB;
}
return g_type=ERROR;
}
void PutBack()
{
//Comment If any error.
if (g_str != g_last_str) g_str = g_last_str;
}
TREE* MakeNode(int type, double value, int oper, TREE* l, TREE* r, TREE* p)
{
TREE* node = (TREE*)malloc(sizeof(TREE));
node->type = type;
node->value = value;
node->oper = oper;
node->left = l;
node->right = r;
node->parent = p;
return node;
}
void DestroyTree(TREE* tree)
{
if(!tree)
return;
if(tree->left)
DestroyTree(tree->left);
if(tree->right)
DestroyTree(tree->right);
free(tree);
}
int Level(int oper)
{
switch(oper)
{
case ATOMM:return 0;
case MUL:case DIV: return 1;
case ADD:case SUB: return 2;
case EXPR:return 32;
}
}
void ShowError()
{
char buff[256]={0};
switch (g_error)
{
case 1:sprintf(buff, "需要一个运算符\t位置%s\n", g_pos);break;
case 2:sprintf(buff, "需要一个表达式\t位置%s\n", g_pos);break;
case 3:sprintf(buff, "括号不匹配\t位置%s\n", g_pos);break;
case 4:sprintf(buff, "空表达式\t位置%s\n", g_pos);break;
case 5:sprintf(buff, "表达式不应该在此结束\t位置%s\n", g_pos);break;
}
printf(buff);
}
TREE* BuildSyntaxTreeImpl()
{
TREE* root, *treeTmp,*new_node;
int use_level=0,state=0;
root=treeTmp= MakeNode(OPERATOR,0,EXPR,0,0,0);
//关键在于下面构造语法树的过程
//原子的优先级很好,对应着直接建立一个结点
//其它的,要比较结点的优先级
//要比较结点先计算,意味着,是作为这个结点的孩子
//否则就是要结点移动
//对应着就表现出现优先级了
while(1)
{
GetNextToken();
switch (g_type)
{
case NUMBER:
new_node=MakeNode(NUMBER, g_value, ATOMM, 0, 0, 0);
use_level=1;
state = 1;
break;
case LB:
++g_braBal;
new_node = BuildSyntaxTreeImpl();
use_level=0;/*括号表达式的优先级很高,不使用优先级比较,直接建为右子树*/
state = 1;
break;
case RB:
--g_braBal;
case END:
{
treeTmp = root->right;
free(root);
treeTmp->parent = NULL;
return treeTmp;
}
default:
new_node = MakeNode(OPERATOR, 0, g_oper, 0, 0, 0);
use_level=1;
state = 0;
}
if(use_level)
{
while(Level(new_node->oper)>=Level(treeTmp->oper))
treeTmp=treeTmp->parent;
new_node->left = treeTmp->right;
treeTmp->right = new_node;
new_node->parent = treeTmp;
treeTmp = new_node;
}
else
{
treeTmp->right = new_node;
new_node->parent = treeTmp;
}
}
}
TREE* BuildSyntaxTree(const char* expression)
{
TREE* tree;
g_braBal = 0;
g_last_str = g_str = expression;
tree = BuildSyntaxTreeImpl();
if (g_braBal)
{
PutBack();
g_error = 3;
g_pos = g_str;
DestroyTree(tree);
tree = 0;
}
return tree;
}
double EvalueTree(TREE* tree)
{
double l, r;
if (!tree) return 0;
if (tree->oper==ATOMM) return tree->value;
l = EvalueTree(tree->left);
r = EvalueTree(tree->right);
switch(tree->oper)
{
case ADD: return l + r;
case SUB: return l - r;
case MUL: return l * r;
case DIV: return l / r;
}
return 0;
}
double Calculate(const char* expression)
{
TREE* tree = BuildSyntaxTree(expression);
double value = 0;
if (!tree) ShowError();
else value = EvalueTree(tree);
DestroyTree(tree);
return value;
}
/*词法分析*/
int g_type,g_error,g_braBal,g_oper;
double g_value;
const char* g_str,*g_last_str,* g_pos;
int GetNextToken()
{
static char tokenBuf[32];
int tokenPos=0,nDot=0;
g_last_str=g_str;
while (*g_str==' ')++g_str; //改动1
if (!*g_str)
return g_type=END;
//Comment: Read a number!
if (isdigit(*g_str))
{
while (isdigit(*g_str)||(*g_str=='.'))
{
tokenBuf[tokenPos++] = *g_str++;
if(*g_str=='.')
nDot++;
}
tokenBuf[tokenPos]= 0;
g_value=atof((const char*)tokenBuf);
if(nDot<=1)
return g_type = NUMBER;
else
return g_type=ERROR;
}
//Comment: Read a operator.
switch (*g_str++)
{
case '+' : g_oper = ADD;return g_type=OPERATOR;
case '-' : g_oper = SUB;return g_type=OPERATOR;
case '*' : g_oper = MUL;return g_type=OPERATOR;
case '/' : g_oper = DIV;return g_type=OPERATOR;
case '(' : return g_type=LB;
case ')' : return g_type=RB;
}
return g_type=ERROR;
}
void PutBack()
{
//Comment If any error.
if (g_str != g_last_str) g_str = g_last_str;
}
TREE* MakeNode(int type, double value, int oper, TREE* l, TREE* r, TREE* p)
{
TREE* node = (TREE*)malloc(sizeof(TREE));
node->type = type;
node->value = value;
node->oper = oper;
node->left = l;
node->right = r;
node->parent = p;
return node;
}
void DestroyTree(TREE* tree)
{
if(!tree)
return;
if(tree->left)
DestroyTree(tree->left);
if(tree->right)
DestroyTree(tree->right);
free(tree);
}
int Level(int oper)
{
switch(oper)
{
case ATOMM:return 0;
case MUL:case DIV: return 1;
case ADD:case SUB: return 2;
case EXPR:return 32;
}
}
void ShowError()
{
char buff[256]={0};
switch (g_error)
{
case 1:sprintf(buff, "需要一个运算符\t位置%s\n", g_pos);break;
case 2:sprintf(buff, "需要一个表达式\t位置%s\n", g_pos);break;
case 3:sprintf(buff, "括号不匹配\t位置%s\n", g_pos);break;
case 4:sprintf(buff, "空表达式\t位置%s\n", g_pos);break;
case 5:sprintf(buff, "表达式不应该在此结束\t位置%s\n", g_pos);break;
}
printf(buff);
}
TREE* BuildSyntaxTreeImpl()
{
TREE* root, *treeTmp,*new_node;
int use_level=0,state=0;
root=treeTmp= MakeNode(OPERATOR,0,EXPR,0,0,0);
//关键在于下面构造语法树的过程
//原子的优先级很好,对应着直接建立一个结点
//其它的,要比较结点的优先级
//要比较结点先计算,意味着,是作为这个结点的孩子
//否则就是要结点移动
//对应着就表现出现优先级了
while(1)
{
GetNextToken();
switch (g_type)
{
case NUMBER:
new_node=MakeNode(NUMBER, g_value, ATOMM, 0, 0, 0);
use_level=1;
state = 1;
break;
case LB:
++g_braBal;
new_node = BuildSyntaxTreeImpl();
use_level=0;/*括号表达式的优先级很高,不使用优先级比较,直接建为右子树*/
state = 1;
break;
case RB:
--g_braBal;
case END:
{
treeTmp = root->right;
free(root);
treeTmp->parent = NULL;
return treeTmp;
}
default:
new_node = MakeNode(OPERATOR, 0, g_oper, 0, 0, 0);
use_level=1;
state = 0;
}
if(use_level)
{
while(Level(new_node->oper)>=Level(treeTmp->oper))
treeTmp=treeTmp->parent;
new_node->left = treeTmp->right;
treeTmp->right = new_node;
new_node->parent = treeTmp;
treeTmp = new_node;
}
else
{
treeTmp->right = new_node;
new_node->parent = treeTmp;
}
}
}
TREE* BuildSyntaxTree(const char* expression)
{
TREE* tree;
g_braBal = 0;
g_last_str = g_str = expression;
tree = BuildSyntaxTreeImpl();
if (g_braBal)
{
PutBack();
g_error = 3;
g_pos = g_str;
DestroyTree(tree);
tree = 0;
}
return tree;
}
double EvalueTree(TREE* tree)
{
double l, r;
if (!tree) return 0;
if (tree->oper==ATOMM) return tree->value;
l = EvalueTree(tree->left);
r = EvalueTree(tree->right);
switch(tree->oper)
{
case ADD: return l + r;
case SUB: return l - r;
case MUL: return l * r;
case DIV: return l / r;
}
return 0;
}
double Calculate(const char* expression)
{
TREE* tree = BuildSyntaxTree(expression);
double value = 0;
if (!tree) ShowError();
else value = EvalueTree(tree);
DestroyTree(tree);
return value;
}
浙公网安备 33010602011771号