📄 cal_process.h
字号:
// Calculator.cpp : Defines the entry point for the console application.
///////////////////////////////////////////////////////////////////////////////
// 作者:Han
// 日期:2009年5月4日
// 名称:可编程计算器
// 功能描述:
// 本计算器可以实现对诸如 3+(1+7)*6+4*((5+4))这样的表达式的计
// 算,目前仅限于带括号的 +,-,/, * 运算
// 实现描述:
//
// E-->TE'
// E'-->+TE'|-TE'|e
// T-->FT'
// T'-->*FT'|/FT'|e
// F-->(E)|num
//
// 程序中使用了一个词法分析函数 yylex,变量yylval代表最近的整数记号的数值。
// '\0'对应着$符号,预示着输入串结束.
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "stdlib.h"
#include "conio.h"
// 这一段是记号的定义
#define ADD 0
#define SUB 7
#define MUL 1
#define DIV 8
#define LBRACE 2
#define RBRACE 3
#define NUM 4
#define END 5
#define OTHER 6
class MyCal
{
public:
char input[200]; // 输入串。
int lookahead;
int pCur;
int yylval;
int error;
// 函数声明
int yylex();
void Match(int t);
double T();
double E_();
double E();
double T_();
double F();
double Cal_pro(char str[]);
bool flag;
};
// 词法分析器,读入一个记号
int MyCal::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 MyCal::Match(int t)
{
if (lookahead == t) lookahead = yylex();
else
{
flag=false;
}
}
// 处理 E-->TE'
double MyCal::E()
{
error=1;
switch (lookahead)
{
case LBRACE: // FIRST(E)={(,num}
case NUM:
return T() + E_(); //??????
default:
flag=false;return 1;
}
}
// 处理 E'-->+TE'|-TE'|e
double MyCal::E_()
{
switch (lookahead)
{
//FIRST(E')={+,-,e}
case ADD: // E'-->+TE' 的情况
Match(ADD);
return T() + E_();
case SUB: // E'-->-TE' 的情况
Match(SUB);
//return -( T() - E_() );
return ( -1*T() + E_() );
// E'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(E')={), $}
case RBRACE:
case END:
return 0;
default:
flag=false;return 1;
}
}
// 处理 T-->FT'
double MyCal::T()
{
switch (lookahead)
{
case LBRACE: // FIRST(FT')={(,num}
case NUM:
return F()*T_();
default:
flag=false;return 1;
}
}
// 处理 T'-->*FT'|/FT'|e
double MyCal::T_()
{
double temp;
switch (lookahead)
{
// FIRST(T')={*|/|e}
case MUL:
Match(MUL);
return F() * T_();
case DIV:
Match(DIV);
temp=F();
if(0==temp)
{
flag=false;
return 1;
}
return 1/( temp / T_()); //理解此处!!!
//(1/F())*T_(); T_()能否为0 ???
// T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,-,),$}
case ADD:
case SUB:
case RBRACE:
case END:
return 1;
default:
flag=false;return 1;
}
}
// 处理 F-->(E)|num
double MyCal::F()
{
double 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:
flag=false;return 1;
}
}
double MyCal::Cal_pro(char str[])
{
flag=true;
pCur = 0;
int i=0;
while(1)
{
if(str[i]!='\0')
{
input[i]=str[i];
i++;
}
else
break;
}
input[i]='\0';
// lookahead 赋初值
lookahead = yylex();
// 调用 开始符号E 对应的处理过程来处理输入串
return E();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -