?? 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 + -