这是一个用文法实现的计算器
源代码在线查看: calculate.cpp
// Calculate.cpp: implementation of the CCalculate class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Calculator.h"
#include "Calculate.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCalculate::CCalculate()
{
pCur=0;
for(int i=0;i input[i]=0;
lookahead=0;
yylval=0;
m_strDisplay="";// 显示串
}
CCalculate::~CCalculate()
{
}
void CCalculate::init()
{
pCur=0;
for(int i=0;i input[i]=0;
lookahead=0;
yylval=0;
m_strDisplay="";// 显示串
}
// 词法分析器,读入一个记号
int CCalculate::yylex()
{
char num[20];
int temp = 0;
// 过滤掉空白
while ( input[pCur]==' ' )//pCur在OnBnClickedButtonEqa()函数内已经被赋成了0。
{
pCur++;
}
// 如果是数字,那么把这个记号的数值计算出来放在 yylval 中
//这里还是在处理单个字符。也就是说是字符串是一个一个字符读入的,一个一个分析的。
while (input[pCur] >= '0' && input[pCur] {
num[temp++] = input[pCur++];
}
if (temp >0)
{
sscanf(num, "%f", &yylval);//做了类型转换,把类型由char转换到int。
return NUM;//把num返回给lookahead.
}
// 其他记号的处理
// 如果读入的不是数字字符,则判断是以下的哪个运算符。
else
switch (input[pCur++]) // 注意:这里指针往前移了一位
{
case '+': return ADD;//把add返回给lookahead.
case '-':return SUB;
case '*':return MUL;//把mul返回给lookahead.
case '/':return DIV;
case '(':return LBRACE;//把lbrace返回给lookahead.
case ')':return RBRACE;//把rbrace返回给lookahead.
case '\0': return END;//把end返回给lookahead.
default: return OTHER;//把other返回给lookahead.
}
}
// 匹配函数,若当前记号与参数相同,则读入下一个记号
void CCalculate::Match(int t)
{
if (lookahead == t)
lookahead = yylex();
else
{
m_strDisplay =" ERROR!!!";
}
}
// 处理 E-->GE'
float CCalculate::E()
{
switch (lookahead)
{
case LBRACE: // FIRST(TE')={(,num}
case NUM:
return T()+E_();
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
// 处理 E'-->+TE'|e
float CCalculate::E_()
{
switch (lookahead)
{
case ADD: // E'-->+TE' 的情况, FIRST(E')={+,e}
Match(ADD);
return T() + E_();
case RBRACE:// E'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(E')={), $}
case SUB:
case DIV:
case END:
return 0;
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
//处理T->ST'
float CCalculate::T()
{
switch (lookahead)
{
case LBRACE:
case NUM:
return S()-T_();
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
//处理T'->-ST'|e
float CCalculate::T_()
{
switch (lookahead)
{
case SUB:
Match(SUB); return S() - T_();
case RBRACE:
case ADD:
case DIV:
case END:
return 0;
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
//处理S->GS'
float CCalculate::S()
{
switch (lookahead)
{
case LBRACE:
case NUM:
return G()/S_();
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
//处理S'->/GS'|e
float CCalculate::S_()
{
switch (lookahead)
{
case DIV:
Match(DIV);
return F() / G_();
case ADD:
case SUB:
case MUL:
case RBRACE:
case END:
return 1;
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
// 处理 G-->FG'
float CCalculate::G()
{
switch (lookahead)
{
case LBRACE: // FIRST(FG')={(,num}
case NUM:
return F()*G_();
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
// 处理 G'-->*FG'|e
float CCalculate::G_()
{
switch (lookahead)
{
case MUL: // FIRST(*FG')={*}
Match(MUL);
return F() * G_();
case ADD: // T'-->e 的情况,这个时候需要处理 FOLLOW集合, FOLLOW(T')={+,),$}
case SUB:
case DIV:
case RBRACE:
case END:
return 1;
default:
m_strDisplay =" ERROR!!!";
}
return 0;
}
// 处理 F-->(E)|num
float CCalculate::F()
{
float 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:
m_strDisplay =" ERROR!!!";
}
return 0;
}