?? 說明.txt
字號:
詞法語法分析類:
/************************************************************************
* 文件名: 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<m_n;i++) //當第2次調用該函數時,就要釋放前1次的資源
delete m_cifa[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<m_n;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 nbool CFenXi::y_ChengXuTi()
{
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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -