學習編譯原理時做的詞法和語法分析程序.詞法和語法分析封裝在一個類CFenXi中, 程序在Visual C++6.0下調試通過.
程序采用單文檔設計,利用了分割窗體技術.
具體實現請參考源代碼!!
/************************************************************************ * 文件名: FenXi.h * 文件描述: 詞法語法分析的頭文件 * 創建人: 程紅秀, 2005年06月15日 * 版本號: 1.0 ************************************************************************/ #if !defined _FENXI_H #define _FENXI_H struct CIFA //保存詞法分析結果 { int nType; //0:錯誤, 1:標志符, 2:數字, 3-:關鍵字和操作符, -1:結束符 int nValue; //二元式中的值 char szText[20]; //單詞 int nAddr; //源文件緩沖區中地址 }; class CFenXi { public: void YuFaFenXi(); //語法分析 void CiFaFenXi(); //詞法分析 int m_nErrAddr; //語法錯誤對應單詞的地址 int m_nErrNo; //語法錯誤代碼 char m_str[20000]; //源程序緩沖區 char m_szErrMsg[100][100]; //錯誤信息表 CIFA * m_cifa[10000]; //詞法分析結果 protected: void init(); int m_nCur; //用于語法分析中,指示詞法分析結果表中當前的位置 int m_n; //用于詞法分析中,用于指示詞法分析結果的個數 char m_szKW[50][20]; //關鍵詞表 int FindInKWTab(char *); /*----------------語法分析函數-----------------------*/ bool y_GuanXi(); //關系 bool y_GuanXiBiaoDaShi(); //關系表達式 bool y_BuErBiaoDaShi(); //布爾表達式 bool y_YinZi(); //因子 bool y_Xiang(); //項 bool y_BiaoDaShi(); //表達式 bool y_ShiCanBiao(); //實參表 bool y_GuoChengYuJu(); //過程語句 bool y_XunHuanYuJu(); //循環語句 bool y_TiaoJianYuJu(); //條件語句 bool y_FuZhiYuJu(); //賦值語句 bool y_FuHeYuJu(); //復合語句 bool y_YuJu(); //語句 bool y_YuJuChuan(); //語句串 bool y_XingCan(); //形參 bool y_XingCanBuFeng(); //形參部分 bool y_GuoChengShengMing(); //過程說明 bool y_BianliangShengMing();//簡便說明 bool y_ShengMing(); //說明 bool y_ShengMingChuan(); //說明串 bool y_ChengXuTi(); //程序體 bool y_ChengXu(); //程序 /*-----------------------------------------------------*/ }; #endif |
/************************************************************************ * 文件名: FenXi.cpp * 文件描述: 詞法語法分析的實現文件 * 創建人: 程紅秀, 2005年06月15日 ************************************************************************/ #include "stdafx.h" #include "fenxi.h" /*================================================================ * 函數名: CiFaFenXi * 功能描述: 詞法分析 (public) * 返回值: void ================================================================*/ void CFenXi::CiFaFenXi() { BOOL flag=false; char token[20]; int k,v; init(); for (int i=0;i int n=0; //用于指示當前的字符 m_n=0; //詞法結果的個數 while (m_str[n]) { if (flag) { while (!((m_str[n]==@#*@#)&&(m_str[n+1]==@#/@#))) { if (m_str[n]) n++; else break; } if (m_str[n]) { n++; n++; flag=false; } } while (1) { while ((m_str[n]==32) || (m_str[n]==9)) n++; if (!((m_str[n]==13) && (m_str[n+1]==10))) break; n++; n++; } if (isalpha(m_str[n])) //字母 { k=0; while (1) { if (k<19) //標志符的長度為20 token[k++]=m_str[n++]; else n++; if (!isalnum(m_str[n])) //如果不是數字或字母就退出 break; } token[k]=0; v=FindInKWTab(token); //查找關鍵詞表 if (v) //如果是關鍵詞 { m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n-k; m_n++; } else //普通標志符 { m_cifa[m_n]=new CIFA; /*----------在詞法分析結果中查找-----------*/ int vv=1; for (int i=0;i if (m_cifa[i]->nType==1) { vv++; if (!::stricmp(m_cifa[i]->szText,token)) m_cifa[m_n]->nValue= m_cifa[i]->nValue; } } m_cifa[m_n]->nValue=vv; /*---------------------------------------*/ m_cifa[m_n]->nType=1; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n-k; m_n++; } } else if (isdigit(m_str[n])) //數字 { k=0; BOOL error=false; while (1) { if (k<=8) token[k++]=m_str[n++]; else { error=true; n++; } if (!isdigit(m_str[n])) break; } token[k]=0; v=::strtol(token,NULL,10); if (error) { m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=1; m_cifa[m_n]->nType=0; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n-k; m_n++; } else { m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=v; m_cifa[m_n]->nType=2; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n-k; m_n++; } } else switch (m_str[n]) //其他符號 { case @#+@#: case @#-@#: case @#*@#: case @#~@#: case @#&@#: case @#|@#: case @#=@#: case @#;@#: case @#.@#: case @#,@#: case @#(@#: case @#)@#: token[0]=m_str[n]; token[1]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; break; case @#\0@#: break; case @#/@#: switch (m_str[n+1]) { case @#*@#: n++; n++; flag=true; break; default: token[0]=m_str[n]; token[1]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; } break; case @#<@#: switch (m_str[n+1]) { case @#=@#: token[0]=m_str[n]; token[1]=m_str[n+1]; token[2]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; n++; break; case @#>@#: token[0]=m_str[n]; token[1]=m_str[n+1]; token[2]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; n++; break; default: token[0]=m_str[n]; token[1]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; } break; case @#>@#: switch (m_str[n+1]) { case @#=@#: token[0]=m_str[n]; token[1]=m_str[n+1]; token[2]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; n++; break; default: token[0]=m_str[n]; token[1]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; } break; case @#:@#: switch (m_str[n+1]) { case @#=@#: token[0]=m_str[n]; token[1]=m_str[n+1]; token[2]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; n++; break; default: token[0]=m_str[n]; token[1]=0; v=FindInKWTab(token); m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=v; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; } break; default: token[0]=m_str[n]; token[1]=0; m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=2; m_cifa[m_n]->nType=0; strcpy(m_cifa[m_n]->szText,token); m_cifa[m_n]->nAddr=n; m_n++; n++; } if (m_n==10000-2) //詞法分析的結果的個數規定為10000 { m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=99; m_cifa[m_n]->nType=0; strcpy(m_cifa[m_n]->szText,""); m_cifa[m_n]->nAddr=n-1; m_n++; break; } } m_cifa[m_n]=new CIFA; m_cifa[m_n]->nValue=0; m_cifa[m_n]->nType=-1; //結束符 strcpy(m_cifa[m_n]->szText,""); m_cifa[m_n]->nAddr=0; m_n++; return; } /*================================================================ * 函數名: FindInKWTab(char * a) * 功能描述: 在關鍵字表中查找 (protected) * 返回值: int (如果找到返回在表中的位置,否則返回0) ================================================================*/ int CFenXi::FindInKWTab(char * a) { for (int i=0;i<50;i++) if (!::stricmp(m_szKW[i],a)) //找到 return i; return 0; //未找到 } /*================================================================ * 函數名: YuFaFenXi * 功能描述: 語法分析 (public) * 返回值: void * 作 者: 程紅秀 2005年6月15日 ================================================================*/ void CFenXi::YuFaFenXi() { if (m_n==0) return; //未進行詞法分析 m_nCur=0; //m_nCur用語指示詞法分析結果表中單詞的位置 y_ChengXu(); //從 程序 開始 return; } /*================================================================ * 函數名: y_ChengXu * 功能描述: 分析整個程序 (protected) * 返回值: bool * 示例: Program abc; 這里是程序體 . ================================================================*/ bool CFenXi::y_ChengXu() //程序 { switch (m_cifa[m_nCur]->nType) { case 3: //從program開始 break; default: m_nErrNo=3; //缺少關鍵字“ program ”! m_nErrAddr=m_nCur; return false; } m_nCur++; //分析下一個單詞 switch (m_cifa[m_nCur]->nType) { case 1: //標志符 break; default: m_nErrNo=4; //program 后缺少標識符! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 30: //; break; default: m_nErrNo=5; //缺少“ ; ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_ChengXuTi()) //分析程序體 return false; switch (m_cifa[m_nCur]->nType) { case 31: //. (程序的最后一個符號) break; default: m_nErrNo=6; //缺少程序結束符“ . ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case -1: //end of cifa break; default: m_nErrNo=96; //源程序結束符 end. 后還有多余內容! m_nErrAddr=m_nCur; return false; } m_nErrNo=0; //語法分析成功 m_nErrAddr=m_nCur; return true; } /*================================================================ * 函數名: y_ChengXuTi * 功能描述: 分析程序體 (protected) * 返回值: bool * 示例: Integer x,y,z; Real a,b; //變量聲明 Procedure ab(Var m,n:Integer; t:Real); //過程聲明 Begin t:=n+m; If m>n then n:=m else t:=m; While n { switch (m_cifa[m_nCur]->nType) { case 5: //procedure case 14: //booleger case 15: //real if (!y_ShengMingChuan()) //聲明串(用;隔開的多個變量或過程聲明) return false; switch (m_cifa[m_nCur]->nType) { case 30: //; break; default: m_nErrNo=5; //缺少“ ; ”符號!" m_nErrAddr=m_nCur; return false; } m_nCur++; break; case 6: //begin break; default: m_nErrNo=7; //缺少《程序體》,應為 begin,integer,real,procedure" m_nErrAddr=m_nCur; return false; } switch (m_cifa[m_nCur]->nType) { case 6: //begin break; default: m_nErrNo=8; //缺少保留字“ begin ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_YuJuChuan()) //語句串 return false; switch (m_cifa[m_nCur]->nType) { case 7: //end break; default: m_nErrNo=10; //缺少保留字“ end ”! m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: y_ShengMingChuan * 功能描述: 聲明串 用;隔開的多個聲明(protected) * 返回值: void ================================================================*/ bool CFenXi::y_ShengMingChuan() { if (!y_ShengMing()) return false; while (m_cifa[m_nCur]->nType==30 && m_cifa[m_nCur+1]->nType!=6) //是; 不是begin { m_nCur++; if (!y_ShengMing()) //遞歸調用 return false; } return true; } /*================================================================ * 函數名: y_ShengMing * 功能描述: 聲明 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_ShengMing() { switch (m_cifa[m_nCur]->nType) { case 14: //booleger case 15: //real if (!y_BianliangShengMing()) //變量聲明 return false; break; case 5: //procedure if (!y_GuoChengShengMing()) //過程聲明 return false; break; default: m_nErrNo=11; //缺少聲明(integer,real,procedure) m_nErrAddr=m_nCur; return false; } return true; } /*================================================================ * 函數名: y_BianliangShengMing * 功能描述: 變量聲明 (protected) * 返回值: void * 示例: Integer x,y,z; ================================================================*/ bool CFenXi::y_BianliangShengMing() { switch (m_cifa[m_nCur]->nType) { case 14: //booleger case 15: //real break; default: m_nErrNo=12; //缺少變量類型 integer 或 real! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=14; //變量聲明后缺少標識符! m_nErrAddr=m_nCur; return false; } m_nCur++; while (m_cifa[m_nCur]->nType==32) //32 , 分析用逗號隔開的連續聲明的幾個變量 { m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=14; //變量聲明后缺少標識符 m_nErrAddr=m_nCur; return false; } m_nCur++; } return true; } /*================================================================ * 函數名: y_GuoChengShengMing * 功能描述: 過程聲明 (protected) * 返回值: void * 示例: Procedure ab(形參); 這里是程序體 ================================================================*/ bool CFenXi::y_GuoChengShengMing() { switch (m_cifa[m_nCur]->nType) { case 5: //procedure break; default: m_nErrNo=15; //缺少保留字“ procedure ”! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=13; //procedure 后缺少標識符! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 33: //( if (!y_XingCanBuFeng()) //形參 return false; break; } switch (m_cifa[m_nCur]->nType) { case 30: //; break; default: m_nErrNo=5; //缺少“ ; ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_ChengXuTi()) //程序體 return false; return true; } /*================================================================ * 函數名: y_XingChan * 功能描述: 形參部分(protected) * 返回值: void * 示例: (Var m,n:Integer; t:Real) ================================================================*/ bool CFenXi::y_XingCanBuFeng() { switch (m_cifa[m_nCur]->nType) { case 33: //( break; default: m_nErrNo=16; //缺少 “ ( ”符號!" m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_XingCan()) return false; while (m_cifa[m_nCur]->nType==30) //; { m_nCur++; if (!y_XingCan()) return false; } switch (m_cifa[m_nCur]->nType) { case 34: //) break; default: m_nErrNo=17; //缺少 “ ) ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: y_XingCan * 功能描述: 分析形參 (protected) * 返回值: void * 示例: Var m,n:Integer; t:Real ================================================================*/ bool CFenXi::y_XingCan() { if (m_cifa[m_nCur]->nType==4) //var m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=18; //"缺少形參標識符 !" m_nErrAddr=m_nCur; return false; } m_nCur++; while (m_cifa[m_nCur]->nType==32) //, 用于分析多個形參的情況 { m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=18; //"缺少形參標識符 !" m_nErrAddr=m_nCur; return false; } m_nCur++; } switch (m_cifa[m_nCur]->nType) { case 35: //: break; default: m_nErrNo=19; //缺少 “ : ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 14: //booleger case 15: //real break; default: m_nErrNo=12; //缺少保留字 integer 或 real! m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: y_YuJuChuan * 功能描述: 語句串,用分號隔開的多個語句 (protected) * 返回值: void * 示例: x:=1;y:=2;z:=3; Call ab(x,y,z); z:=4+z+(1+2+6+x)*3*y*5+7; If ~ 3<=x & y<>4 then z:=0; y:=219; z:=37; x:=y*z ================================================================*/ bool CFenXi::y_YuJuChuan() { if (!y_YuJu()) return false; while (m_cifa[m_nCur]->nType==30) //; { m_nCur++; if (!y_YuJu()) return false; } return true; } /*================================================================ * 函數名: y_YuJu * 功能描述: 語句 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_YuJu() { switch (m_cifa[m_nCur]->nType) { case 6: //begin if (!y_FuHeYuJu()) return false; break; case 1: //id if (!y_FuZhiYuJu()) return false; break; case 8: //if if (!y_TiaoJianYuJu()) return false; break; case 11: //while if (!y_XunHuanYuJu()) return false; break; case 13: //call if (!y_GuoChengYuJu()) return false; break; default: m_nErrNo=9; //缺少《語句》,應為 begin,ID,if,while,call m_nErrAddr=m_nCur; return false; } return true; } /*================================================================ * 函數名: y_FuHeYuJu * 功能描述: 復合語句 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_FuHeYuJu() { switch (m_cifa[m_nCur]->nType) { case 6: //begin break; default: m_nErrNo=8; //缺少保留字“ begin ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_YuJuChuan()) //遞歸調用 return false; switch (m_cifa[m_nCur]->nType) { case 7: //end break; default: m_nErrNo=10; //"缺少保留字“ end ”! m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: y_FuZhiYuJu * 功能描述: 賦值語句 (protected) * 返回值: void * 示例: y:=219; ================================================================*/ bool CFenXi::y_FuZhiYuJu() { switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=20; //缺少標識符! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 29: //:= break; default: m_nErrNo=21; //缺少賦值符號“ := ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_BiaoDaShi()) return false; return true; } /*================================================================ * 函數名: y_TiaoJianYuJu * 功能描述: 條件語句 (protected) * 返回值: void * 示例: If m>n then n:=m else t:=m; ================================================================*/ bool CFenXi::y_TiaoJianYuJu() { switch (m_cifa[m_nCur]->nType) { case 8: //if break; default: m_nErrNo=22; //缺少保留字“ if ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_BuErBiaoDaShi()) //表達式 return false; switch (m_cifa[m_nCur]->nType) { case 9: //then break; default: m_nErrNo=23; //缺少保留字“ then ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_YuJu()) //語句 return false; switch (m_cifa[m_nCur]->nType) { case 10: //else break; default: return true; } m_nCur++; if (!y_YuJu()) //語句 return false; return true; } /*================================================================ * 函數名: y_XunHuanYuJu * 功能描述: 循環語句 (protected) * 返回值: void * 示例: While n { switch (m_cifa[m_nCur]->nType) { case 11: //while break; default: m_nErrNo=24; m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_BuErBiaoDaShi()) //表達式 return false; switch (m_cifa[m_nCur]->nType) { case 12: //do break; default: m_nErrNo=25; //缺少保留字“ do ”! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_YuJu()) return false; return true; } /*================================================================ * 函數名: y_GuoChengYuJu * 功能描述: 過程語句 (protected) * 返回值: void * 示例: Call ab(x,y,z); ================================================================*/ bool CFenXi::y_GuoChengYuJu() { switch (m_cifa[m_nCur]->nType) { case 13: //call break; default: m_nErrNo=26; //缺少保留字“ call ”! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 1: //id break; default: m_nErrNo=27; //缺少被調過程名標識符! m_nErrAddr=m_nCur; return false; } m_nCur++; switch (m_cifa[m_nCur]->nType) { case 33: //( break; default: return true; } if (!y_ShiCanBiao()) //表達式 return false; return true; } /*================================================================ * 函數名: y_ShiCanBiao * 功能描述: 實參表 (protected) * 返回值: void *示例: Call ab(x,y,z); ================================================================*/ bool CFenXi::y_ShiCanBiao() { switch (m_cifa[m_nCur]->nType) { case 33: //( break; default: m_nErrNo=16; //缺少 “ ( ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; if (!y_BiaoDaShi()) //表達式 return false; while (m_cifa[m_nCur]->nType==32) //, { m_nCur++; if (!y_BiaoDaShi()) return false; } switch (m_cifa[m_nCur]->nType) { case 34: //) break; default: m_nErrNo=17; //缺少 “ ) ”符號 m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: y_BiaoDaShi * 功能描述: 表達式 (protected) * 返回值: void * 示例: z:=4+z+(1+2+6+x)*3*y*5+7; ================================================================*/ bool CFenXi::y_BiaoDaShi() { if (!y_Xiang()) return false; while (m_cifa[m_nCur]->nType==16) //+ { m_nCur++; if (!y_Xiang()) return false; } return true; } /*================================================================ * 函數名: y_Xiang * 功能描述: 項 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_Xiang() { if (!y_YinZi()) return false; while (m_cifa[m_nCur]->nType==18)//* { m_nCur++; if (!y_YinZi()) return false; } return true; } /*================================================================ * 函數名: y_YinZi * 功能描述: 因子 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_YinZi() { switch (m_cifa[m_nCur]->nType) { case 1: //id m_nCur++; break; case 2: //num m_nCur++; break; case 33: //( m_nCur++; if (!y_BiaoDaShi()) //遞歸調用 return false; switch (m_cifa[m_nCur]->nType) { case 34: //) break; default: m_nErrNo=17; //缺少 “ ) ”符號! m_nErrAddr=m_nCur; return false; } m_nCur++; break; default: m_nErrNo=28; //缺少《因子》,應為 (,ID,NUMBER" m_nErrAddr=m_nCur; return false; } return true; } /*================================================================ * 函數名: y_BuErBiaoDaShi * 功能描述: 布爾表達式 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_BuErBiaoDaShi() { switch (m_cifa[m_nCur]->nType) { case 20: //~ m_nCur++; if (!y_BuErBiaoDaShi()) return false; break; case 33: //( case 1: //id case 2: //num if (!y_GuanXiBiaoDaShi()) return false; while (m_cifa[m_nCur]->nType==21 || m_cifa[m_nCur]->nType==22) // & | { m_nCur++; if (!y_BuErBiaoDaShi()) return false; } break; default: m_nErrNo=29; //"缺少《布爾表達式》,應為 ~,(,ID,NUMBER" m_nErrAddr=m_nCur; return false; } return true; } /*================================================================ * 函數名: y_GuanXiBiaoDaShi * 功能描述: 關系表達式 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_GuanXiBiaoDaShi() { if (!y_BiaoDaShi()) //表達式 return false; if (!y_GuanXi()) //關系 return false; if (!y_BiaoDaShi()) //表達式 return false; return true; } /*================================================================ * 函數名: y_GuanXi * 功能描述: 關系 (protected) * 返回值: void ================================================================*/ bool CFenXi::y_GuanXi() { switch (m_cifa[m_nCur]->nType) { case 23: //< case 24: //<= case 25: //> case 26: //>= case 27: //= case 28: //<> break; default: m_nErrNo=30; //缺少關系(<,<=,>,>=,=,<>)! m_nErrAddr=m_nCur; return false; } m_nCur++; return true; } /*================================================================ * 函數名: init * 功能描述: 用于初始化關鍵字表和錯誤信息表 (protected) * 返回值: void ================================================================*/ void CFenXi::init() { strcpy(m_szKW[0],""); strcpy(m_szKW[1],"");//標識符 strcpy(m_szKW[2],"");//正整數 strcpy(m_szKW[3],"program"); strcpy(m_szKW[4],"var"); strcpy(m_szKW[5],"procedure"); strcpy(m_szKW[6],"begin"); strcpy(m_szKW[7],"end"); strcpy(m_szKW[8],"if"); strcpy(m_szKW[9],"then"); strcpy(m_szKW[10],"else"); strcpy(m_szKW[11],"while"); strcpy(m_szKW[12],"do"); strcpy(m_szKW[13],"call"); strcpy(m_szKW[14],"integer"); strcpy(m_szKW[15],"real"); strcpy(m_szKW[16],"+"); strcpy(m_szKW[17],"-"); strcpy(m_szKW[18],"*"); strcpy(m_szKW[19],"/"); strcpy(m_szKW[20],"~"); strcpy(m_szKW[21],"&"); strcpy(m_szKW[22],"|"); strcpy(m_szKW[23],"<"); strcpy(m_szKW[24],"<="); strcpy(m_szKW[25],">"); strcpy(m_szKW[26],">="); strcpy(m_szKW[27],"="); strcpy(m_szKW[28],"<>"); strcpy(m_szKW[29],":="); strcpy(m_szKW[30],";"); strcpy(m_szKW[31],"."); strcpy(m_szKW[32],","); strcpy(m_szKW[33],"("); strcpy(m_szKW[34],")"); strcpy(m_szKW[35],":"); strcpy(m_szKW[36],"/*"); strcpy(m_szKW[37],"*/"); strcpy(m_szKW[38],""); strcpy(m_szKW[39],""); strcpy(m_szKW[40],""); strcpy(m_szKW[41],""); strcpy(m_szKW[42],""); strcpy(m_szKW[43],""); strcpy(m_szKW[44],""); strcpy(m_szKW[45],""); strcpy(m_szKW[46],""); strcpy(m_szKW[47],""); strcpy(m_szKW[48],""); strcpy(m_szKW[49],""); strcpy(m_szErrMsg[0],"正確!"); strcpy(m_szErrMsg[1],"數字位數過長!"); strcpy(m_szErrMsg[2],"非法字符!"); strcpy(m_szErrMsg[3],"缺少關鍵字“ program ”!"); strcpy(m_szErrMsg[4],"program 后缺少標識符!"); strcpy(m_szErrMsg[5],"缺少“ ; ”符號!"); strcpy(m_szErrMsg[6],"缺少程序結束符“ . ”符號!"); strcpy(m_szErrMsg[7],"缺少《程序體》,應為 begin,integer,real,procedure"); strcpy(m_szErrMsg[8],"缺少保留字“ begin ”!"); strcpy(m_szErrMsg[9],"缺少《語句》,應為 begin,ID,if,while,call"); strcpy(m_szErrMsg[10],"缺少保留字“ end ”!"); strcpy(m_szErrMsg[11],"缺少《聲明》,應為 integer,real,procedure"); strcpy(m_szErrMsg[12],"缺少保留字 integer 或 real!"); strcpy(m_szErrMsg[13],"procedure 后缺少標識符!"); strcpy(m_szErrMsg[14],"變量聲明后缺少標識符!"); strcpy(m_szErrMsg[15],"缺少保留字“ procedure ”!"); strcpy(m_szErrMsg[16],"缺少 “ ( ”符號!"); strcpy(m_szErrMsg[17],"缺少 “ ) ”符號!"); strcpy(m_szErrMsg[18],"缺少形參標識符 !"); strcpy(m_szErrMsg[19],"缺少 “ : ”符號!"); strcpy(m_szErrMsg[20],"缺少標識符!"); strcpy(m_szErrMsg[21],"缺少賦值符號“ := ”!"); strcpy(m_szErrMsg[22],"缺少保留字“ if ”!"); strcpy(m_szErrMsg[23],"缺少保留字“ then ”!"); strcpy(m_szErrMsg[24],"缺少保留字“ while ”!"); strcpy(m_szErrMsg[25],"缺少保留字“ do ”!"); strcpy(m_szErrMsg[26],"缺少保留字“ call ”!"); strcpy(m_szErrMsg[27],"缺少被調過程名標識符!"); strcpy(m_szErrMsg[28],"缺少《因子》,應為 (,ID,NUMBER"); strcpy(m_szErrMsg[29],"缺少《布爾表達式》,應為 ~,(,ID,NUMBER"); strcpy(m_szErrMsg[30],"缺少《關系》!"); strcpy(m_szErrMsg[31],"變量名不能和過程名相同!"); strcpy(m_szErrMsg[32],"標識符重復聲明!"); strcpy(m_szErrMsg[33],"未聲明標識符!"); strcpy(m_szErrMsg[34],"不能直接引用過程名!"); strcpy(m_szErrMsg[35],"不能從real轉換為integer類型!"); strcpy(m_szErrMsg[36],"不能用常數作實參!"); strcpy(m_szErrMsg[37],"變參應為變量!"); strcpy(m_szErrMsg[38],"實參個數不足!"); strcpy(m_szErrMsg[39],"只有integer和integer才能比較!"); strcpy(m_szErrMsg[40],"不能這樣調用過程!"); strcpy(m_szErrMsg[41],""); strcpy(m_szErrMsg[42],""); strcpy(m_szErrMsg[43],""); strcpy(m_szErrMsg[96],"源程序結束符 end. 后還有多余內容!"); strcpy(m_szErrMsg[97],"語法錯誤太多,終止語法分析!"); strcpy(m_szErrMsg[98],"源程序不正常結束!"); strcpy(m_szErrMsg[99],"內存不足!詞法分析終止!"); } |