//strcmp(s1,s2) 当s1大于s2时,返回1 ,s1小于s2时,返回-1,相等时,返回0
#include "stdio.h"
#include "ctype.h"
#include "string.h"
#include "math.h"
#define MAX 256
#define STACK_SIZE 128
#define WORD_LEN 8
#define POP 1
#define PUSH 0
#define ERR -1
#define END 2
#define OPER 0
#define NUM 1
#define WORD 2
#define ADD 1
#define SUB 2
#define MUL 3
#define DIV 4
#define POW 5
#define FAC 6
#define BRA_L 7
#define BRA_R 8
#define SIN 9
#define COS 10
#define TAN 11
#define CTG 12
#define LG 13 //以10为底的常用对数
//#define LN 14
//#define LOG 15
//行标为当前操作符代号,列标为栈顶元素代号
//2表示计算结束,0表示当前操作符进栈,1表示栈顶操作符出栈
// \0 + - * / ^ ! ( ) sin cos tg ctg lg
int Priority[14][14]={2, 1, 1, 1, 1, 1, 1,-1,-1, 1, 1, 1, 1, 1, /* \0 */
0, 1, 1, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* + */
0, 1, 1, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* - */
0, 0, 0, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* * */
0, 0, 0, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 1, /* / */
0, 0, 0, 1, 1, 1, 1, 0,-1, 0, 0, 0, 0, 0, /* ^ */
0, 0, 0, 0, 0, 0, 1, 0,-1, 0, 0, 0, 0, 0, /* ! */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* ( */
-1,1, 1, 1, 1, 1, 1, 1,-1, 1, 1, 1, 1, 1, /* ) */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* sin */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* cos */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* tg */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0, /* ctg */
0, 0, 0, 0, 0, 0,-1, 0,-1, 0, 0, 0, 0, 0}; /* lg */
char KeyWord[36][WORD_LEN+1]={"sin", //前12个为函数,多余的用于扩展
"cos",
"tan",
"tg",
"ctg",
"lg",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"help", // 后面为命令,多余的为扩展
"version",
"set",
"digit", //精度,小数点后的位数
"color",
"radian", //弧度
"degree", //角度
"file",
"clr",
"clear",
"window", //窗口模式
"fullscr", //全屏模式
"",
"",
"",
"",
"",
"",
"",
"",
""};
int OperCode(char c)
{
int code;
switch(c)
{
case '\0':code=0;br
eak;
case '+':code=1;break;
case '-':code=2;break;
case '*':code=3;break;
case '/':code=4;break;
case '^':code=5;break;
case '!':code=6;break;
case '(':code=7;break;
case ')':code=8;break;
case 's':code=9;break; //sin
case 'c':code=10;break; //cos
case 't':code=11;break; //tg
case 'C':code=12;break; //ctg
case 'l':code=13;break; //log
default:code=-1;break;
};
return code;
}
int WordCode(char* word)
{
int i;
for(i=0;i<25;i++)
if(strcmp(KeyWord[i],word)==0)
break;
if(i>=25)
return -1;
else
return i;
}
void help()
{
printf("显示帮助信息!\n");
return;
}
void version()
{
printf("显示版本信息!\n");
return;
}
void Err(int errcode,int position,char *p)
{
printf("\n ERR:%d Position:%d %s",errcode,position,p);
return;
}
double long factorial(int i)
{
if(i==1 || i==0)
return(1.0);
else
return(i*factorial(i-1));
}
main()
{
char Expression[MAX+1];
int Operator[STACK_SIZE];
int OperStackTop;
double long Number[STACK_SIZE];
int NumStackTop;
double long NumList[STACK_SIZE];
int NumCursor,NumListSize;
int OperList[STACK_SIZE];
int OperCursor,OperListSize;
int WordList[STACK_SIZE];
int WordCursor,WordListSize;
int Index[MAX+1];
int IndexCursor,IndexSize;
char Word[WORD_LEN+1];
double long num,num1,num2,weight,tempnum;
int Oper;
int isDecimal,isErr,isNumber,isEnd;
char CurrentOper;
int i,j,k,m,n;
char ch;
num=0.0;
num1=0.0;
num2=0.0;
tempnum=0.0;
Oper=-1;
while(1)
{
for(i=0;i<=MAX;i++) //表达式初始化,中间表索引初始化
{
Expression[i]='\0';
Index[i]=-1;
}
for(i=0;i
Operator[i]='0';
Number[i]=0.0;
NumList[i]=0.0;
OperList[i]=-1;
WordList[i]=-1;
}
NumStackTop=-1; //栈顶指针初始化
OperStackTop=0; //操作符栈压入\0
Operator[OperStackTop]=OperCode('\0');
NumCursor=0; //各种中间表指针初始化,各种中间表的长度初始化
NumListSize=0;
OperCursor=0;
OperListSize=0; //操作符表中先写入第一个操作符'\0'
WordCursor=0;
WordListSize=0;
IndexCursor=0;
IndexSize=0;
// Index[0]=OPER;
printf("Cal>"); //初始化完成,输出提示符
i=0;
while((ch=getchar())!='\n')
{
if(i>MAX) /*输入超长,则出错*/
{
Err(0,i,"输入的表达式长度超过规定值!\n");
isErr=1;
break;
}
if(isupper(ch))
ch=tolower(ch);
Expression[i]=ch;
i++;
}
if(isErr==1)
{
isErr=0;
continue;
}
if(strlen(Expression)==0) //直接回车
continue;
if(strcmp("end",Expression)==0 ||strcmp("exit",Expression)==0 || strcmp("quit",Expr
ession)==0)
break;
//一下代码为编译预处理,主要处理负号,并检查括号是否配对
k=0;
for(i=0;Expression[i]!='\0';i++)
{
if((i==0&&Expression[i]=='-') || (i>0&&Expression[i]=='-'&&Expression[i-1]=='('))
{
for(j=strlen(Expression);j>i;j--)
Expression[j]=Expression[j-1];
Expression[i]='0';
}
if(Expression[i]=='(') //检查括号
k++;
if(Expression[i]==')')
k--;
}
if(k>0) //如果括号不配对
{
Err(1,-1,"缺少右括号 )\n");
continue;
}
if(k<0)
{
Err(1,-1,"缺少左括号 (\n");
continue;
}
//编译预处理结束
i=0; //词法分析
while(1)
{
if(Expression[i]=='\0')
{
OperList[OperListSize]=OperCode(Expression[i]);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
// printf("IndexSize=%d,Index[IndexSize]=%d,Expression[i]=%c\n",IndexSize,Index[IndexSize],Expression[i]);
break;
}
isDecimal=0;
isNumber=0;
while(isdigit(Expression[i])||Expression[i]=='.') //读取数字
{
isNumber=1;
if(Expression[i]=='.')
{
if((i<(MAX-1) && !isdigit(Expression[i+1])) || (i+1)==MAX) //不正确的小数点位置
{
Err(2,i,"小数点位置不正确!\n");
isErr=1;
isNumber=0;
i++;
break;
}
isDecimal=1;
weight=0.1;
i++;
continue;
}
if(isDecimal==0)
num=num*10.0+(double long)(Expression[i]-'0');
else
{
num=num+(double long)(Expression[i]-'0')*weight;
weight=weight*0.1;
}
i++;
} //数字读完
if(isErr==1)
break;
if(isNumber==1) //如果刚才成功读取了数字,则数字入栈
{
NumList[NumListSize]=num;
NumListSize++;
isNumber=0;
num=0.0;
Index[IndexSize]=NUM;
// printf("IndexSize=%d,Index[IndexSize]=%d\n",IndexSize,Index[IndexSize]);
IndexSize++;
}
for(k=0;k<=WORD_LEN;k++)
Word[k]='\0';
j=0;
while(isalpha(Expression[i]))
{
if(j>=WORD_LEN) //超过长度仍然未匹配,则出错
{
Err(3,i,"单词长度超过规定值/未定义的单词:");
printf("%s\n",Word);
isErr=1;
break;
}
Word[j]=Expression[i];
j++;
// printf("WORD:%s\n",Word);
if(WordCode(Word)==-1) //匹配不成功
{
if(!isalpha(Expression[i+1]))//匹配不成功,但是下一个字符已经不是字母,
{
Err(4,i,"未定义的单词:"); //则出错,并跳出循环
printf("%s\n",Word);
isErr=1;
break;
} //匹配不成功且还能继续读取字符,则继续读取下一个字母
i++;
continue;
}
else //匹配成功,则单词入表,读取下一个字符
{
switch(Wo
rdCode(Word))
{
case 0:ch='s';
break;
case 1:ch='c';
break;
case 2:
case 3:ch='t';
break;
case 4:ch='C';
break;
case 5:ch='l';
break;
default:ch='\0';
WordList[WordListSize]=WordCode(Word);
WordListSize++;
Index[IndexSize]=WORD;
IndexSize++;
break;
};
if(ch!='\0')
{
OperList[OperListSize]=OperCode(ch);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
}
i++;
break;
}
} //单词读完
if(isErr==1)
break;
if(Expression[i]==' ')
i++;
if(!isdigit(Expression[i]) && !isalpha(Expression[i]) && Expression[i]!='\0')
{
if(OperCode(Expression[i])==-1)
{
isErr=1;
Err(5,i,"未定义的操作符:");
printf("%c\n",Expression[i]);
break;
}
else
{
OperList[OperListSize]=OperCode(Expression[i]);
OperListSize++;
Index[IndexSize]=OPER;
IndexSize++;
i++;
}
} //操作符读完
if(isErr==1)
break;
} //词法分析结束
if(isErr==1)
{
isErr=0;
continue;
}
/* for(k=0;k
for(k=0;k
for(k=0;k
for(k=0;k
printf("\n\n IndexCursor=%d IndexSize=%d,\n",IndexCursor,IndexSize);
printf("OperStacktop=%d,Operator[OperStackTop]=%d,NumStackTop=%d\n",OperStackTop,Operator[OperStackTop],NumStackTop);
// continue;
*/
isEnd=0;
IndexCursor=0;
while(1)
{
if(Index[IndexCursor]==NUM)
{
if(NumCursor<0 || NumListSize<0)
{
Err(10,-1,"索引列表与操作数列表信息不匹配\n");
isErr=1;
break;
}
NumStackTop++;
Number[NumStackTop]=NumList[NumCursor];
NumCursor++;
IndexCursor++;
continue;
} //数字处理
if(Index[IndexCursor]==OPER)
{
m=OperList[OperCursor];
n=Operator[OperStackTop];
switch(Priority[m][n])
{
case ERR:Err(20,IndexCursor,"不可预见的错误!\n");
isErr=1;
break;
case PUSH:OperStackTop++;
Operator[OperStackTop]=m;
OperCursor++;
IndexCursor++;
break;
case END:isEnd=1;
break;
case POP:Oper=Operator[OperStackTop];
OperStackTop--;
switch(Oper)
{
case BRA_L: IndexCursor++
;
OperCursor++;
break;
case ADD:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;
tempnum=num1+num2;
NumStackTop++;
Number[NumStackTop]=tempnum;
num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(11,IndexCursor,"加法运算缺少操作数!\n");
isErr=1;
}
break;
case SUB:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;
tempnum=num1-num2;
NumStackTop++;
Number[NumStackTop]=tempnum;
num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(12,IndexCursor,"减法运算缺少操作数!\n");
isErr=1;
}
break;
case MUL:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;
tempnum=num1*num2;
NumStackTop++;
Number[NumStackTop]=tempnum;
num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(13,IndexCursor,"乘法运算缺少操作数!\n");
isErr=1;
}
break;
case DIV:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
if(num2==0.0)
{
Err(14,IndexCursor,"除数为 0 ,不能进行除法运算!\n");
isErr=1;
break;
}
num1=Number[NumStackTop];
NumStackTop--;
tempnum=num1/num2;
NumStackTop++;
Number[NumStackTop]=tempnum;
num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(15,IndexCursor,"除法运算缺少操作数!\n");
isErr=1;
}
break;
case POW:if(NumStackTop>=1)
{
num2=Number[NumStackTop];
NumStackTop--;
num1=Number[NumStackTop];
NumStackTop--;
tempnum=pow(num1,num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num1=0.0;
num2=0.0;
tempnum=0.0;
}
else
{
Err(16,IndexCursor,"乘方运算缺少操作数!\n");
isErr=1;
}
break;
case FAC:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
tempnum=factorial(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(17,IndexCursor,"阶乘运算缺少操作数!\n");
isErr=1;
}
break;
case SIN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
tempnum=sin(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(18,IndexCursor,"正弦函数缺少参数!\n");
isErr=1;
}
break;
case COS:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
tempnum=cos(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(19,IndexCursor,"余弦函数缺少参数!\n");
isErr=1;
}
break;
case TAN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
tempnum=tan(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(20,IndexCursor,"正切函数
缺少参数!\n");
isErr=1;
}
break;
case CTG:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
tempnum=1.0/tan(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(21,IndexCursor,"余切函数缺少参数!\n");
isErr=1;
}
break;
/* case LN:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
if(num2<=0.0)
{
Err(20,IndexCursor,"自然对数函数真数:");
printf(" %f 小于0!\n",num2);
isErr=1;
break;
}
tempnum=log(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(17,IndexCursor,"自然对数函数缺少参数!\n");
isErr=1;
}
break; */
case LG:if(NumStackTop>=0)
{
num2=Number[NumStackTop];
NumStackTop--;
if(num2<=0.0)
{
Err(23,IndexCursor,"常用对数函数真数:");
printf(" %f 小于0!\n",num2);
isErr=1;
break;
}
tempnum=log10(num2);
NumStackTop++;
Number[NumStackTop]=tempnum;
num2=0.0;
tempnum=0.0;
}
else
{
Err(22,IndexCursor,"常用对数函数缺少参数!\n");
isErr=1;
}
break;
default:Err(100,IndexCursor,"运算符(代码:");
printf(" %d )暂不支持!\n",Oper);
isErr=1;
break;
/*#define SIN 9
#define COS 10
#define TAN 11
#define CTG 12
#define LOG 13 */
}; //switch 语句结束
break;
};//switch
if(isErr==1 || isEnd==1)
break;
continue;
} //运算符处理
if(Index[IndexCursor]==WORD)
{
printf(" 单词尚未处理!\n");
break;
}//在这里处理单词
}//核心计算结束
if(isErr==1)
{
isErr=0;
continue;
}
if(NumStackTop>0)
{
Err(1000,-1,"多余的操作数:");
printf("%f!\n",Number[NumStackTop]);
}
else
if(NumStackTop==0 && isEnd==1)
{
if(fabs(Number[NumStackTop])>1e20)
printf(" %.20e\n",Number[NumStackTop]);
else
printf(" %f\n",Number[NumStackTop]);
isEnd=0;
}
}//主循环结束
}//主函数结束