c++编写可编程计算器遇到的问题
源代码如下
可是有些问题
除法不对了
例如键入3/3
结果却是9?
如何改?
#include "stdafx.h"
#include "stdlib.h"
#include "conio.h"
// 这一段是记号的定义
#define ADD 0
#define SUB 1
#define MUL 2
#define DIV 3
#define LBRACE 4
#define RBRACE 5
#define NUM 6
#define END 7
#define OTHER 8
char input[200]; // 输入串。
int lookahead;
int pCur;
int yylval;
// 函数声明
int yylex();
void Match(int t);
long T();
long E_(int*);
long E_();
long T_(int*);
long F();
// 词法分析器,读入一个记号
int yylex()
{
char num[20];
int temp = 0;
// 过滤掉空白
while ( input[pCur]==' ' ) pCur++;
// 如果是数字,那么把这个记号的数值计算出来放在 yylval 中
while (input[pCur] >= '0' && input[pCur] <= '9'){
num[temp++] = input[pCur++];
}
if (temp >0)
{
sscanf(num, "%d", &yylval);
return NUM;
}
// 其他记号的处理
switch (input[pCur++]) // 注意:这里指针往前移了一位
{
case '+': return ADD;
case '-': return SUB;
case '*':return MUL;
case '/': return DIV;
case '(':return LBRACE;
case ')':return RBRACE;
case '\0': return END;
default: return OTHER;
}
}
// 匹配函数,若当前记号与参数相同,则读入下一个记号
void Match(int t)
{
if (lookahead == t) lookahead = yylex();
else
{
printf("\n Error\n");
exit(0);
}
}
// 处理 T-->FT'
long T()
{
int flag,temp1,temp2;
switch (lookahead)
{
case LBRACE: // FIRST(FT')={(,num}
case NUM:
temp1=F();
temp2=T_(&flag);
if(flag=1) return temp1*temp2;
return temp1/temp2;
default:
printf("\n Error\n");
exit(0);
}
}
// 处理 E'-->+TE'|e
long E_(int*pflag)
{
int flag,temp1,temp2;
switch (lookahead)
{
case ADD: // E'-->+TE' 的情况, FIRST(E')={+,e}
*pflag=1;
Match(ADD);
temp1=T();
temp2=E_(&flag);
if(flag==1) return temp1+temp2;
case SUB:
*pflag=0;
Match(SUB);
temp1=T();
temp2=E_(&flag);
if(flag==1) return temp1+temp2;
else return temp1-temp2;
case RBRACE:// E'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(E')={), $}
case END:
return 0;
default:
printf("\n Error\n");
exit(0);
}
}
// 处理 E-->TE'
long E()
{
int flag,temp1,temp2;
switch (lookahead)
{
case LBRACE: // FIRST(TE')={(,num}
case NUM:
temp1=T();
temp2=E_(&flag);
if(flag==1) return temp1+temp2;
else return temp1-temp2;
case END: // FOLLOW(E)={),$}
return 0;
default:
printf("\n Error\n");
exit(0);
}
}
// 处理 T'-->*FT'|e
long T_(int*pflag)
{
int flag,temp1,temp2;
switch (lookahead)
{
case MUL: // FIRST(*FT')={*}
*pflag=1;
Match(MUL);
temp1=F();
temp2=T_(&flag);
if(flag==1) return temp1*temp2;
else return temp1/temp2;
case DIV:
*pflag=0;
Match(DIV);
temp1=F();
temp2=T_(&flag);
if(flag==1) return temp1*temp2;
else return temp1/temp2;
case ADD: // T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,),$}
case SUB:
case RBRACE:
case END:
return 1;
default:
printf("\n Error\n");
exit(0);
}
}
// 处理 F-->(E)|num
long F()
{
int temp;
switch(lookahead)
{
case LBRACE: // FIRST((E))={(}
Match(LBRACE);
temp = E();
Match(RBRACE);
return temp;
case NUM: // FIRST(num) = {num}
temp = yylval;
Match(NUM);
return temp;
default:
printf("\n Error\n");
exit(0);
}
}
int main(int argc, char* argv[])
{
pCur = 0;
// 读入输入串
printf("Please input the string:");
scanf("%s",input);
// lookahead 赋初值
lookahead = yylex();
// 调用 开始符号E 对应的处理过程来处理输入串
printf("The answer is %d\n", E());
getch();
return 0;
}
问题点数:0、回复次数:4Top
1 楼lynnboy(lynnboy)回复于 2004-11-04 18:58:01 得分 0
处理 T'-->*FT'|e
long T_(int*pflag)
{
int flag,temp1,temp2;
switch (lookahead)
{
case MUL: // FIRST(*FT')={*}
*pflag=1;
Match(MUL);
temp1=F();
temp2=T_(&flag);
if(flag==1) return temp1*temp2;
else return temp1/temp2;
case DIV:
*pflag=0;
Match(DIV);
temp1=F();
temp2=T_(&flag);
///////////// if(flag==1) return temp1*temp2;
//////////// else return temp1/temp2;
/// 是不是应该
if (flag == 1) return temp1/temp2;
else return temp1*temp2;
case ADD: // T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,),$}
case SUB:
case RBRACE:
case END:
return 1;
default:
printf("\n Error\n");
exit(0);
}
}
Top
2 楼lynnboy(lynnboy)回复于 2004-11-04 18:58:24 得分 0
你考虑过除零异常吗?Top
3 楼nokia7600()回复于 2004-11-04 20:04:30 得分 0
不对吧?Top
4 楼dhtyidyygy(英雄无用吾之地)回复于 2004-11-04 20:58:22 得分 0
你考虑过优先级吗?
你是不是把各运算符所对应的代码都搞错了?Top




