這兩個星期按下面語法圖封裝了一個詞法與語法的類,因爲水平有限現在傳上來,希望各位高手指正^_^
以下是語法圖:
頭文件:
struct CIFA //存儲分析出的詞
{
CString work; //分析出的單詞
int type; //1 關鍵字,2 標識符,3 數字,4或7 錯誤,5 操作符,6 statement number
int loca; //該詞在緩衝的位置
// int value; //該詞的值
CIFA * next; //連接下一單詞
};
class CFenXi
{
public:
BOOL GetErrFlag();
void PrintYuFaMsg(CString &str);
void YuFaFenXi();
void PrintCiFaErrMsg(CString& str);
void CifaFenxi();
CFenXi();
virtual ~CFenXi();
CIFA *m_head; //詞法分析結果
CString m_code; //源程序緩衝
protected:
BOOL IsRepeat();
BOOL Expression();
BOOL KW_VARIABLE();
BOOL NextWord();
void NextYuJu();
int WhichKW(CString str);
BOOL Condition();
BOOL Statement();
BOOL Program();
BOOL IsRem(CString str);
BOOL IsKeyWord(CString str);
BOOL IsString(CString str);
BOOL KW_FOR();
BOOL KW_END();
BOOL KW_NEXT();
BOOL KW_UNLOOP();
BOOL KW_IF();
BOOL KW_REM();
BOOL KW_GOTO();
BOOL KW_GOSUB();
BOOL KW_RETURN();
BOOL KW_INPUT(int num);
BOOL KW_PRINT(int num);
CIFA* cur; //指向當前分析的詞
char m_keyWord[15][10]; //關鍵字表
int m_keyWordNum; //分析的單詞個數
char m_operor[15][5]; //操作符表
char m_errMes[35][100]; //錯誤信息表
int m_errors[50]; //記錄語法錯誤
int m_errNum; //記錄語法錯誤個數
int m_errFlag; //詞法錯誤標誌(詞法有錯爲非零)
int m_staNum[50]; //記錄statement number
int m_stanum; //statement Number 個數
};
CPP文件:
CFenXi::CFenXi()
{
m_errFlag = 0;
m_head = NULL;
strcpy(m_keyWord[0],"FOR");
strcpy(m_keyWord[1],"END");
strcpy(m_keyWord[2],"NEXT");
strcpy(m_keyWord[3],"UNLOOP");
strcpy(m_keyWord[4],"IF");
strcpy(m_keyWord[5],"REM");
strcpy(m_keyWord[6],"GOTO");
strcpy(m_keyWord[7], "GOSUB");
strcpy(m_keyWord[8],"RETURN");
strcpy(m_keyWord[9],"INPUT");
strcpy(m_keyWord[10],"PRINT");
strcpy(m_keyWord[11],"TO");
strcpy(m_keyWord[12],"THEN");
strcpy(m_keyWord[13],"program");
// strcpy(m_keyWord[13],"CR");
m_keyWordNum = 14;
strcpy(m_operor[0],"=");
strcpy(m_operor[1],"-");
strcpy(m_operor[2],"+");
strcpy(m_operor[3],"*");
strcpy(m_operor[4],"/");
strcpy(m_operor[5],"(");
strcpy(m_operor[6],")");
strcpy(m_operor[7],"<");
strcpy(m_operor[8],">");
strcpy(m_operor[9],",");
char temp[2];
temp[0] = (char)13;
strcpy(m_operor[10],temp); //m_operor[10]存儲回車
strcpy(m_errMes[0],"標識符定義錯誤或存在非法字符;標識符定義只能有一個字母打頭,後面跟數字串");
strcpy(m_errMes[1],"漏了一邊括號");
strcpy(m_errMes[2],"缺少CR或該語句後存在多餘語句");
strcpy(m_errMes[3],"缺少statement number");
strcpy(m_errMes[4],"註釋行有錯");
strcpy(m_errMes[5],"缺少關鍵字“ program ”");
strcpy(m_errMes[6],"program與statement間有多餘信息");
strcpy(m_errMes[7],"缺少statement number");
strcpy(m_errMes[8],"FOR的結構應爲FOR 標識符 = 標識符或常量 TO 標識符或常量");
strcpy(m_errMes[9],"END後除了‘CR’外沒有其它字符");
strcpy(m_errMes[10],"NEXT後只跟一個標識符");
strcpy(m_errMes[11],"UNLOOP後只跟一個標識符");
strcpy(m_errMes[12],"IF結構錯誤 正確爲(標識符或常數 <或=或〉標識符或常數)");
strcpy(m_errMes[13],"REM語句出錯");
strcpy(m_errMes[14],"GOTO後應跟statement number");
strcpy(m_errMes[15],"GOSUB後應跟statement number");
strcpy(m_errMes[16],"statement Number 與另一重複");
strcpy(m_errMes[17],"INPUT後跟標識符,若有多個(不超過三個)標識符用逗號分開");
strcpy(m_errMes[18],"PRINT後跟標識符,若有多個(不超過三個)標識符用逗號分開");
strcpy(m_errMes[19],"variable後應爲 = 表達式 CR");
strcpy(m_errMes[20],"statement後不能直接換行");
strcpy(m_errMes[21],"一次語句只能輸入三個數");
strcpy(m_errMes[22],"PRINT後跟標識符,若有多個(不超過三個)標識符用逗號分開");
strcpy(m_errMes[23],"statement後只能跟關鍵字或變量");
}
CFenXi::~CFenXi()
{
}
void CFenXi::CifaFenxi()
{//詞法分析
m_stanum = 0;
m_errFlag = 0; //出錯標誌初始爲0
if(m_head)
{
CIFA* p;
CIFA* q;
p = m_head->next;
while(p) //當再次運行函數,將上次所佔資源釋放
{
q = p;
p = p->next;
delete q;
}
m_head = NULL; //表頭清空
}
m_head = new CIFA; //帶頭節點的鏈表存儲詞法分析結果
CString room; //當前分析的詞
room.Empty();
CIFA* last = m_head; //記錄表尾
BOOL m_isKG = TRUE; //判斷是否讀到一個詞
int m_n; //記錄詞在緩衝的位置
int flag = 1; //0表示字符串,1表示操作符或空格
for(int i = 0;i<=m_code.GetLength();i++)//分析源代碼
{
if(m_isKG) //遇到空格或操作符時的處理
{
m_n = i;
room.Empty();
m_isKG = FALSE;
}
if(i < m_code.GetLength())//當前字符不是m_code的最後一位,則操作
{
int tt = m_code.GetAt(i);
if(tt != ' ' && !(tt>=40&&tt<=45) && tt!=47 && !(tt>=60&&tt<=62) && tt!=13 && tt!=10)
//如果不是空格或不是操作符,繼續讀字符
{
room += m_code.GetAt(i);
flag = 0;//將標誌轉成字符串
continue;
}
}
// CIFA* cur; //存放當前分析的詞
if(flag == 0)
{//一個詞讀完,進行處理
cur = new CIFA;
cur->work = room;
int n = 0; //room標識符的類型,1爲非法,2爲數字與字符混合
//3爲數字,4爲字符,0爲沒定義
int m; //循環控制標誌
for(m = 0;m<room.GetLength();m++)//分析當前詞
{
if(!((room.GetAt(m)>=65 && room.GetAt(m)<=90) ||
(room.GetAt(m)>=97 && room.GetAt(m)<=122) ||
(room.GetAt(m)>=48 && room.GetAt(m)<58)))
{//遇到非法字符,出錯
m_errFlag = 1;
cur->type = 4;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
n=1;
break; //檢測到非法字符,確定單詞爲非法串,退出循環
}
if(room.GetAt(m)>=48 && room.GetAt(m)<58)
{//判斷是否純數字
if(n!=1 && (n==0||n==3))
n = 3;
if(n!=1 && (n==4||n==2))
n = 2;//確定該詞爲數字與字符混合
}
if((room.GetAt(m)>=65 && room.GetAt(m)<=90) ||
(room.GetAt(m)>=97 && room.GetAt(m)<=122))
{///判斷是否純字符
if(n!=1 && (n==0||n==4))
n=4;
if(n!=1 && (n==3||n==2))
n = 2;//確定該詞爲數字與字符混合
}
}
if(n == 3)
{//該詞類型爲數字
if(last->work == "CR")
{
if(IsRepeat())
cur->type = 7;
else
cur->type = 6;
}
else
cur->type = 3;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
if(n == 4)
{
if(m==1)//當只有一個字母時爲標識符
{
cur->type = 2;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
else//當大於一個字母時爲標識符
{
if(IsKeyWord(room))//是否爲關鍵字
{
if(IsRem(room))//如果爲 註釋
{
BOOL m_yinHao = FALSE;
CString strRem;
for(int h = i;;h++)//過濾註釋
{
if(m_code[h] == 13)
break;
if(m_code[h] == ' ')
continue;
else
strRem += m_code.GetAt(h);
// if((m_code[h] == 34&&m_yinHao==FALSE)
// m_yinHao = TRUE;
}
if(IsString(strRem)) //分析註釋
cur->type = 1;
else
{
cur->type = 4;
m_errFlag = 1;
}
i = h;
}
else
cur->type = 1;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
else
{//大於兩個字符的純字母組成的串爲非法串
cur->type = 4;
m_errFlag = 1;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
}
}
if(n == 2)
{
if(room.GetAt(0)>=48 && room.GetAt(0)<58)
{//不符合標識符定義規則
m_errFlag = 1;
cur->type = 4;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
if((room.GetAt(0)>=65 && room.GetAt(0)<=90) ||
(room.GetAt(0)>=97 && room.GetAt(0)<=122))
{
for(m = 1;m<room.GetLength();m++)
{//標識符定義爲一字符打頭,後面跟數字.不能跟數字以外的符號
if(room.GetAt(m)<48 || room.GetAt(m)>=58)
break;
}
if(m<room.GetLength())
{//不符合標識符定義規則
m_errFlag = 1;
cur->type = 4;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}
else
{//標識符
cur->type = 2;
cur->loca = m_n;
cur->next = NULL;
last->next = cur;
last = cur;
}//if
}//if
}//for
}//if
if(i < m_code.GetLength())//當前字符不是m_code的最後一位,則操作
{
flag = 1; //將標誌轉成操作符
int t = m_code.GetAt(i);
if((t>=40&&t<=45) || t==47 || (t>=60&&t<=62) || t==13)
{//噹噹前字符爲操作符時
cur = new CIFA;
if(t == 13) //如果當前是回車,且上個單詞不是回車,則
if(last->work != "CR")
{
cur->work = "CR";
cur->type = 1; //回車爲關鍵字
i++;
}
else
{//如果連續兩個回車,則過濾
m_isKG = TRUE;
continue;
}
else
{
cur->work = m_code.GetAt(i);
cur->type = 5; //其他爲操作符
}
cur->loca = i;
cur->next = NULL;
last->next = cur;
last = cur;
}
}
m_isKG = TRUE;
}
}
BOOL CFenXi::IsKeyWord(CString str)
{//判斷是否爲關鍵字
char *temp;
// for(int i = 0;i<str.GetLength();i++)
// temp[i] = str.GetAt(i);
temp = str.GetBuffer(str.GetLength());
for(int m = 0;m<m_keyWordNum;m++)
if(strcmp(temp,m_keyWord[m]) == 0)//兩字符串相等
return TRUE;
return FALSE;
}
void CFenXi::PrintCiFaErrMsg(CString &str)
{//打印詞法分析的錯誤信息
CIFA * p;
p = m_head->next;
int num = 0; //錯誤單詞個數
CString temp;
str.Empty();
str.Format("詞法分析");
str += 13; //回車
str += 10; //換行
str += "屬性中1 關鍵字,2 標識符,3 數字,4或7 錯誤,5 操作符,6 statement number";
str += 13; //回車
str += 10; //換行
str += 13; //回車
str += 10; //換行
str += "屬性 單詞 ";
str += 13; //回車
str += 10; //換行
while(p)
{
temp.Empty();
switch(p->type)
{
case 1:
temp += '1';//關鍵字
break;
case 2:
temp += '2';//標識符
break;
case 3:
temp += '3';//數字
break;
case 4:
temp += '4';//出錯
break;
case 5:
temp += '5';//操作符
break;
case 6:
temp += '6';//statement number
break;
case 7:
temp += '7';//statement number出現重複
break;
}
temp += " ";
temp += p->work;
if(p->type == 4)
{
temp += " ";
if(p->work == "REM")
temp += m_errMes[4];//顯示出錯信息
else
temp += m_errMes[0];//顯示出錯信息
num++;
}
if(p->type == 7)
{
temp += " ";
temp += m_errMes[16];//顯示出錯信息
num++;
}
temp += 13;
temp += 10;
str += temp;
p = p->next;
}
str += 13; //回車
str += 10; //換行
char a[5];
itoa(num,a,10); //錯誤個數
str += "錯誤個數 ";
str += a;
}
BOOL CFenXi::IsRem(CString str)
{//判斷是否爲註釋行
if(str.GetLength()>3)
return FALSE;//不與關鍵字REM匹配放回FALSE
for(int i = 0;i<str.GetLength();i++)
{
if(str.GetAt(i) != m_keyWord[5][i])
break;
}
if(i<str.GetLength())
return FALSE;//不與關鍵字REM匹配放回FALSE
return TRUE;//與關鍵字REM匹配放回TRUE
}
BOOL CFenXi::IsString(CString str)
{//分析string
if(str.GetAt(0) != 34) //判斷第一個字符是否爲 "
return FALSE;
else
if(str.GetAt(str.GetLength()-1) != 34)
return FALSE;
//註釋在兩雙引號內則返回TRUE
return TRUE;
}
void CFenXi::YuFaFenXi()
{
Program();
}
BOOL CFenXi::Program()
{//程序分析開始
cur = m_head->next; //cur獲得的一個分析的單詞
m_errNum = 0; //錯誤信息初始爲0
if(cur->work != "program")
m_errors[m_errNum++] = 5; //缺少關鍵字“ program ”
NextWord(); //分析下一單詞
while(1)
{
if(cur->work != "CR")
{
NextWord();
if(m_errNum == 1)
m_errors[m_errNum++] = 6; //program與statement間有多餘信息
}
else
break; //遇到statement number時退出
}
NextWord();
while(1)
{
if(cur)
{
if(Statement()) //分析statement
return TRUE; //遇到END返回TRUE
}
else
break;
}
return FALSE;
}
BOOL CFenXi::Statement()
{//分析statement
if(cur->type != 6)
{
NextYuJu();
m_errors[m_errNum++] = 7; //缺少statement number
NextWord();
NextWord();
return FALSE;
}
NextWord();
int flag = 1;
switch(WhichKW(cur->work))//各個語句分析
{
case 0: //"FOR"
if(!KW_FOR())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 8; //FOR的結構應爲FOR 標識符 = 標識符或常量 TO 標識符或常量
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 8; //FOR的結構應爲FOR 標識符 = 標識符或常量 TO 標識符或常量
}
break;
case 1: //"END"
if(!KW_END())
{
m_errors[m_errNum++] = 9; //END後除了‘CR’外沒有其它字符
}
return TRUE; //END後沒有字符返回真
break;
case 2: //"NEXT"
if(!KW_NEXT())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 10; //NEXT後只跟一個標識符
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 10; //NEXT後只跟一個標識符
}
break;
case 3: //"UNLOOP"
if(!KW_UNLOOP())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 11; //UNLOOP後只跟一個標識符
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 11; //UNLOOP後只跟一個標識符
}
break;
case 4: //"IF"
if(!KW_IF())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 12; //IF結構錯誤
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 12; //IF結構錯誤
}
break;
case 5: //"REM"
if(!KW_REM())
{
NextYuJu();
m_errors[m_errNum++] = 13; //REM出錯
}
break;
case 6: //"GOTO"
if(!KW_GOTO())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 14; //GOTO後跟statement number
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 14; //GOTO後跟statement number
}
break;
case 7: //"GOSUB"
if(!KW_GOSUB())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 15; //GOSUB後跟statement number
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 15; //GOSUB後跟statement number
}
break;
case 8: //"RETURN"
if(!KW_RETURN())
m_errors[m_errNum++] = 16;
break;
case 9: //"INPUT"
if(!KW_INPUT(0))
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 17; //INPUT後跟標識符,若有多個(不超過三個)標識符用逗號分開
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 17; //INPUT後跟標識符,若有多個(不超過三個)標識符用逗號分開
}
break;
case 10: //"PRINT"
if(!KW_PRINT(0))
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 18; //PRINT後跟標識符,若有多個(不超過三個)標識符用逗號分開
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 18; //PRINT後跟標識符,若有多個(不超過三個)標識符用逗號分開
}
break;
default:
if(cur->type == 2)
{
if(!KW_VARIABLE())
{
if(cur->work == "CR")
{
NextWord();
m_errors[m_errNum++] = 19; //variable後應爲 = 表達式 CR
return FALSE;
}
else
NextYuJu();
m_errors[m_errNum++] = 19; //variable後應爲 = 表達式 CR
}
}
else
{
if(cur->work != "CR")
NextYuJu();
else
{
NextWord();
m_errors[m_errNum++] = 20; //statement後不能直接換行
return FALSE;
}
m_errors[m_errNum++] = 23; //statement後只能跟關鍵字或變量
}
}
NextWord();
if(cur->work != "CR")
{
NextYuJu();
m_errors[m_errNum++] = 2; //缺少CR或該語句後存在多餘語句
NextWord();
NextWord();
}
else
NextWord();
return FALSE;
}
BOOL CFenXi::Condition()
{//IF的判斷條件
if(cur->work.GetAt(0) != '(')
return FALSE;
NextWord();
if(!(cur->type == 2 || cur->type == 3))
return FALSE;
NextWord();
if(!(cur->work.GetAt(0) == '<' || cur->work.GetAt(0) == '=' || cur->work.GetAt(0) == '>'))
return FALSE;
NextWord();
if(!(cur->type == 2 || cur->type == 3))
return FALSE;
NextWord();
if(cur->work.GetAt(0) != ')')
return FALSE;
return TRUE;
}
int CFenXi::WhichKW(CString str)
{//判斷關鍵字所對應的序號
for(int i = 0;i<11;i++)
{
for(int j = 0;j<str.GetLength();j++)
if(str.GetAt(j) != m_keyWord[i][j])
break;
if(j==str.GetLength())
return i; //表示相應的關鍵字
}
return -1; //表示是標示符
}
BOOL CFenXi::KW_FOR()//FOR的結構應爲FOR 標識符 = 標識符或常量 TO 標識符或常量 CR
{
NextWord();
if(cur->type != 2)//FOR後缺標識符
return FALSE;
NextWord();
if(cur->work.GetAt(0) != '=')//FOR中的 = 有誤
return FALSE;
NextWord();
if(!(cur->type == 2||cur->type == 3)) //標識符出錯
return FALSE;
NextWord();
if(cur->work != "TO")//TO 出錯
return FALSE;
NextWord();
if(!(cur->type == 2||cur->type == 3)) //標識符出錯
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_END()//END後除了‘CR’外沒有其它字符
{
NextWord();
if(!cur) //爲空則結束
return TRUE;
if(cur->work != "CR") //不空又不與CR相符,出錯
return FALSE;
if(cur->next) //空又與CR相符,但後面還有字符,出錯
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_NEXT()//NEXT後只跟一個標識符
{
NextWord();
if(cur->type != 2)
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_UNLOOP()//UNLOOP後只跟一個標識符
{
NextWord();
if(cur->type != 2)
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_IF()//結構 (標識符或常數 <或=或〉標識符或常數)
{
NextWord();
if(!Condition())
return FALSE;
NextWord();
if(cur->work != "THEN")
return FALSE;
NextWord();
if(cur->type != 3)
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_REM()
{
return TRUE;
}
BOOL CFenXi::KW_GOTO()//GOTO後跟statement number
{
NextWord();
if(cur->type != 3)
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_GOSUB()//GOSUB後跟statement number
{
NextWord();
if(cur->type != 3)
return FALSE;
return TRUE;
}
BOOL CFenXi::KW_INPUT(int num)
{//INPUT後跟標識符,若有多個(不超過三個)標識符用逗號分開
NextWord();
if(cur->type != 2) //不是標識符返回FALSE
return FALSE;
// NextWord();
if(cur->next->work != "CR")
{
NextWord();
if(cur->work.GetAt(0) != ',')//若有多個逗號分開
return FALSE;
else
{
if(num < 2)
{
if(!KW_INPUT(++num))
return FALSE;
}
else
{
NextYuJu();
// m_errors[m_errNum++] = 21;//一次語句只能輸入三個數
return FALSE;
}
}
}
return TRUE;
}
BOOL CFenXi::KW_RETURN()
{
return TRUE;
}
BOOL CFenXi::KW_PRINT(int num)
{//PRINT後跟標識符,若有多個(不超過三個)標識符用逗號分開
NextWord();
if(cur->type != 2) //不是標識符返回FALSE
return FALSE;
if(cur->next->work != "CR")
{
NextWord();
if(cur->work.GetAt(0) != ',')//若有多個逗號分開
return FALSE;
else
{
if(num < 2)
{
if(!KW_PRINT(++num))
return FALSE;
}
else
{
NextYuJu();
// m_errors[m_errNum++] = 21;//一次語句只能輸入三個數
return FALSE;
}
}
}
return TRUE;
}
void CFenXi::PrintYuFaMsg(CString &str)
{
str.Empty();
char a[5];
if(m_errNum == 0)
{
str += 13; //回車
str += 10; //換行
str += " 源程序語法正確";
return ;
}
str += "語法分析結果:";
str += 13; //回車
str += 10; //換行
for(int i = 1;i<=m_errNum;i++)
{
itoa(i,a,10); //錯誤排列
str += "錯誤";
str += a;
str += " ";
str += m_errMes[m_errors[i-1]];
str += 13; //回車
str += 10; //換行
}
str += 13; //回車
str += 10; //換行
itoa(m_errNum,a,10); //錯誤個數
str += "錯誤個數 ";
str += a;
}
void CFenXi::NextYuJu()
{//將指針移到下一語句
while(1)
{
if(!cur->next)
break;
if(cur->next->work == "CR")
break;
NextWord();
}
}
BOOL CFenXi::NextWord()
{//指向下一單詞
if(cur)
{
cur = cur->next;
return TRUE;
}
else //當沒有單詞時返回FALSE
return FALSE;
}
BOOL CFenXi::KW_VARIABLE()
{
NextWord();
if(cur->work.GetAt(0) != '=')
return FALSE;
NextWord();
if(!Expression())
return FALSE;
return TRUE;
}
BOOL CFenXi::Expression()
{//表達式
if(!(cur->type == 2 || cur->type == 3 || cur->work.GetAt(0) == '('))
return FALSE;//不是變量或數字或因子,返回FALSE
else
{
if(cur->work.GetAt(0) == '(')
{
NextWord();
if(!Expression())//如果因子則判斷裏面是否表達式
return FALSE;
if(cur->work.GetAt(0) != ')')
return FALSE;
else
{
if(cur->next->work == "CR")//語句結束則返回TRUE
return TRUE;
}
}
}
if(cur->next->work != "CR")
NextWord();
else
return TRUE;//語句結束則返回TRUE
if(!(cur->work.GetAt(0) == '+' || cur->work.GetAt(0) == '-'
|| cur->work.GetAt(0) == '*' || cur->work.GetAt(0) == '/'))
if(cur->work.GetAt(0) != ')')
return FALSE;//不是以上操作符返回FALSE
else
return TRUE;
NextWord();
if(!Expression())//遞歸
return FALSE;
return TRUE;
}
BOOL CFenXi::GetErrFlag()//得到此法分析時的錯誤標誌
{
return m_errFlag;
}
BOOL CFenXi::IsRepeat()//statement Number 是否重複出現
{
char a[10];
for(int i = 0;i<cur->work.GetLength();i++)
a[i] = cur->work.GetAt(i);
a[i] = '/0';
int t = atoi(a);
for(int j = 0;j<m_stanum;j++)//查找有沒有重複statement number
{
if(t == m_staNum[j])
break;
}
m_staNum[m_stanum++] = t;
if(j<m_stanum-1)
return TRUE;
return FALSE;
}