词法语法分析类:
/************************************************************************
* 文件名: 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日
================================================================*/