📄 ccifafenxi.cpp
字号:
m_nErrNo=30; //缺少关系符(<,<=,>,>=,=,<>)!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
return true;
}
/******************************************
* 函数名: GuoChengShengMing
* 功能描述: 过程声明 (protected)
* 返回值: void
* 示例:
Procedure ab(形参);
这里是程序体
******************************************/
bool CFenXi::GuoChengShengMing()
{
if( m_cifa[m_nCur]->nType !=5) //procedure
{
m_nErrNo=15; //缺少保留字“ procedure ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if(m_cifa[m_nCur]->nType !=1) //id
{
m_nErrNo=13; //procedure 后缺少标识符!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if( m_cifa[m_nCur]->nType !=33) //(
{
m_nErrNo=16; //缺少 “ ( ”符号!"
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!XingCan())
return false;
while (m_cifa[m_nCur]->nType==30) //;
{
m_nCur++;
if (!XingCan())
return false;
}
if( m_cifa[m_nCur]->nType !=34) //)
{
m_nErrNo=17; //缺少 “ ) ”符号!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if(m_cifa[m_nCur]->nType != 30) //;
{
m_nErrNo=5; //缺少;!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!ChengXuTi()) //程序体
return false;
return true;
}
/******************************************
* 函数名: XingCan
* 功能描述: 分析形参 (protected)
* 返回值: void
* 示例: Var m,n:Integer; t:Real
*******************************************/
bool CFenXi::XingCan()
{
if (m_cifa[m_nCur]->nType==4) //var
{
m_nCur++;
}
if( m_cifa[m_nCur]->nType !=1) //id
{
m_nErrNo=18; //"缺少形参标识符 !"
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
while (m_cifa[m_nCur]->nType==32) //, 用于分析多个形参的情况
{
m_nCur++;
if(m_cifa[m_nCur]->nType !=1) //id
{
m_nErrNo=18; //"缺少形参标识符 !"
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
}
if( m_cifa[m_nCur]->nType !=35) //:
{
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;
}
/******************************************************
* 函数名: YuJuChuan
* 功能描述: 语句串,用分号隔开的多个语句 (protected)
* 返回值: void
********************************************************/
bool CFenXi::YuJuChuan()
{
if (!YuJu())
return false;
while (m_cifa[m_nCur]->nType==30) //;
{
m_nCur++;
if (!YuJu())
return false;
}
return true;
}
/*****************************************
* 函数名: FuHeYuJu
* 功能描述: 复合语句 (protected)
* 返回值: void
******************************************/
bool CFenXi::FuHeYuJu()
{
if( m_cifa[m_nCur]->nType !=6) //begin,但是这语句是不可能执行的
{
m_nErrNo=8; //缺少保留字“ begin ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!YuJuChuan()) //递归调用
return false;
if( m_cifa[m_nCur]->nType !=7) //end
{
m_nErrNo=10; //"缺少保留字“ end ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
return true;
}
/******************************************
* 函数名: BiaoDaShi
* 功能描述: 表达式 (protected)
* 返回值: void
* 示例: z:=4+z+(1+2+6+x)*3*y*5+7;
*******************************************/
bool CFenXi::BiaoDaShi()
{
if (!Xiang())
return false;
while (m_cifa[m_nCur]->nType==16) //+
{
m_nCur++;
if (!Xiang())
return false;
}
return true;
}
/**************************************
* 函数名: Xiang
* 功能描述: 项 (protected)
* 返回值: void
***************************************/
bool CFenXi::Xiang()
{
if (!YinZi())
return false;
while (m_cifa[m_nCur]->nType==18)//*
{
m_nCur++;
if (!YinZi())
return false;
}
return true;
}
/**************************************
* 函数名: YinZi
* 功能描述: 因子 (protected)
* 返回值: void
****************************************/
bool CFenXi::YinZi()
{
switch (m_cifa[m_nCur]->nType)
{
case 1: //id
m_nCur++;
break;
case 2: //num
m_nCur++;
break;
case 33: //(
m_nCur++;
if (!BiaoDaShi()) //递归调用
return false;
if(m_cifa[m_nCur]->nType != 34) //)
{
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;
}
/**************************************
* 函数名: FuZhiYuJu
* 功能描述: 赋值语句 (protected)
* 返回值: void
* 示例: y:=219;
***************************************/
bool CFenXi::FuZhiYuJu()
{
if( m_cifa[m_nCur]->nType !=1) //id,但这句是不可能被执行的
{
m_nErrNo=20; //缺少标识符!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if( m_cifa[m_nCur]->nType !=29 ) //:=
{
m_nErrNo=21; //缺少赋值符号“ := ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!BiaoDaShi())
return false;
return true;
}
/***************************************
* 函数名: BoolBiaoDaShi
* 功能描述: 布尔表达式 (protected)
* 返回值: void
****************************************/
bool CFenXi::BoolBiaoDaShi()
{
switch (m_cifa[m_nCur]->nType)
{
case 20: //~
m_nCur++;
if (!BoolBiaoDaShi())
return false;
break;
case 33: //(
case 1: //id
case 2: //num
if (!GuanXiBiaoDaShi())
return false;
while (m_cifa[m_nCur]->nType==21 || m_cifa[m_nCur]->nType==22) // & |
{
m_nCur++;
if (!BoolBiaoDaShi())
return false;
}
break;
default:
m_nErrNo=29; //"缺少《布尔表达式》,应为 ~,(,ID,NUMBER"
m_nErrAddr=m_nCur;
return false;
}
return true;
}
/**********************************
* 函数名: YuJu
* 功能描述: 语句 (protected)
* 返回值: void
*************************************/
bool CFenXi::YuJu()
{
switch (m_cifa[m_nCur]->nType)
{
case 6: //begin
if (!FuHeYuJu())
return false;
break;
case 1: //id
if (!FuZhiYuJu())
return false;
break;
case 8: //if
if (!TiaoJianYuJu())
return false;
break;
case 11: //while
if (!XunHuanYuJu())
return false;
break;
case 13: //call
if (!GuoChengYuJu())
return false;
break;
case 38: //write
if(!XieYuJv())
return false;
break;
case 39: //read
if(!DuYuJv())
return false;
break;
default:
m_nErrNo=9; //缺少《语句》,应为 begin,ID,if,while,call
m_nErrAddr=m_nCur;
return false;
}
return true;
}
/*********************************************
* 函数名: XunHuanYuJu
* 功能描述: 循环语句 (protected)
* 返回值: void
*********************************************/
bool CFenXi::XunHuanYuJu()
{
if(m_cifa[m_nCur]->nType != 11 ) //while,这句不可能执行
{
m_nErrNo=24;
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!BoolBiaoDaShi()) //表达式
return false;
if(m_cifa[m_nCur]->nType != 12 ) //do
{
m_nErrNo=25; //缺少保留字“ do ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!YuJu())
return false;
return true;
}
/**************************************************************
* 函数名: TiaoJianYuJu
* 功能描述: 条件语句 (protected)
* 返回值: void
* 示例: If m>n then n:=m else t:=m;
****************************************************************/
bool CFenXi::TiaoJianYuJu()
{
if(m_cifa[m_nCur]->nType !=8 ) //if,这语句不可能执行
{
m_nErrNo=22; //缺少保留字“ if ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!BoolBiaoDaShi()) //表达式
return false;
if(m_cifa[m_nCur]->nType != 9 ) //then
{
m_nErrNo=23; //缺少保留字“ then ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!YuJu()) //语句
return false;
if(m_cifa[m_nCur]->nType != 10 ) //else
return true;
m_nCur++;
if (!YuJu()) //语句
return false;
return true;
}
/***************************************
*函数名:CiFaFenXi
*所属类:CFenXi
*功能:从输入串分离出一个个的单词
****************************************/
void CFenXi::init()
{
strcpy(m_kw[0],"");
strcpy(m_kw[1],"");//标识符
strcpy(m_kw[2],"");//正整数
strcpy(m_kw[3],"program");
strcpy(m_kw[4],"var");
strcpy(m_kw[5],"procedure");
strcpy(m_kw[6],"begin");
strcpy(m_kw[7],"end");
strcpy(m_kw[8],"if");
strcpy(m_kw[9],"then");
strcpy(m_kw[10],"else");
strcpy(m_kw[11],"while");
strcpy(m_kw[12],"do");
strcpy(m_kw[13],"call");
strcpy(m_kw[14],"integer");
strcpy(m_kw[15],"real");
strcpy(m_kw[16],"+");
strcpy(m_kw[17],"-");
strcpy(m_kw[18],"*");
strcpy(m_kw[19],"/");
strcpy(m_kw[20],"~");
strcpy(m_kw[21],"&");
strcpy(m_kw[22],"|");
strcpy(m_kw[23],"<");
strcpy(m_kw[24],"<=");
strcpy(m_kw[25],">");
strcpy(m_kw[26],">=");
strcpy(m_kw[27],"=");
strcpy(m_kw[28],"<>");
strcpy(m_kw[29],":=");
strcpy(m_kw[30],";");
strcpy(m_kw[31],".");
strcpy(m_kw[32],",");
strcpy(m_kw[33],"(");
strcpy(m_kw[34],")");
strcpy(m_kw[35],":");
strcpy(m_kw[36],"/*");
strcpy(m_kw[37],"*/");
strcpy(m_kw[38],"write");
strcpy(m_kw[39],"read");
strcpy(m_kw[40],"");
strcpy(m_kw[41],"");
strcpy(m_kw[42],"");
strcpy(m_kw[43],"");
strcpy(m_kw[44],"");
strcpy(m_kw[45],"");
strcpy(m_kw[46],"");
strcpy(m_kw[47],"");
strcpy(m_kw[48],"");
strcpy(m_kw[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],"缺少程序体");
strcpy(m_szErrMsg[8],"缺少关键字 begin !");
strcpy(m_szErrMsg[9],"缺少语句");
strcpy(m_szErrMsg[10],"缺少关键字 end !");
strcpy(m_szErrMsg[11],"缺少声明");
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],"缺少因子");
strcpy(m_szErrMsg[29],"缺少布尔表达式");
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],"源程序结束符. 后还有多余内容!");
strcpy(m_szErrMsg[97],"语法错误太多,终止语法分析!");
strcpy(m_szErrMsg[98],"源程序不正常结束!");
strcpy(m_szErrMsg[99],"内存不足!词法分析终止!");
}
/***************************************
*函数名:XieYuJv
*所属类:CFenXi
*功能:往屏幕写
****************************************/
bool CFenXi::XieYuJv()
{
if(m_cifa[m_nCur]->nType != 38)//write,这块不可能被执行
{
//待定错误类型
return false;
}
m_nCur++;
if(!BiaoDaShi())
return false;
return true;
}
/***************************************
*函数名:DuYuJv
*所属类:CFenXi
*功能:从键盘读一整数给一整型变量
****************************************/
bool CFenXi::DuYuJv()
{
if(m_cifa[m_nCur]->nType != 39)//read,这块不可能被执行
{
//待定错误类型
return false;
}
m_nCur++;
if(m_cifa[m_nCur]->nType != 1)//标识符
{
//待定错误类型
return false;
}
m_nCur++;
return true;
}
/***************************************
*函数名:IsRedefine
*所属类:CFenXi
*功能:检查所用变量是否是否定义
*如://有时可能没有procedure
****************************************/
bool CFenXi::IsRedefine(char *str)//未为real型做检查
{
for(int i=m_nCur; i<nLength; i++)
{
if(m_cifa[i]->nType==14)//Interger
{
int j=i+1;
for( ; j<nLength ; j++,i++)
{
if(m_cifa[j]->nType==1 && strcmp(m_cifa[j]->szText,str))//是标识符
return true;
if(m_cifa[j+1]->nType==32)//要是豆号,继续
continue;
if(m_cifa[j+1]->nType==30)//碰到分号,一条定义语句结束
break;
if(!(m_cifa[j]->nType==14))//不再是定义语句
return false;
}
}
}
return false;
}
/**********************************************
*函数名:GetCurrentError
*所属类:CFenXi
*功能:返回语法分析中的错误,但只能返回一个错误
* 因为在语法分析中,一旦有错即返回了的
***********************************************/
void CFenXi::ShowCurrentError()
{
cout<<m_szErrMsg[m_nErrNo]<<endl;
}
/**********************************************
*函数名:IsDefine
*所属类:CFenXi
*功能:判断标识符否已经定义
***********************************************/
bool CFenXi::IsDefine(char *str)
{
for(int i=0; i<nLength; i++)
{
if(m_cifa[i]->nType==14)//Interger
{
int j=i+1;
for( ; j<nLength ; j++,i++)
{
if(m_cifa[j]->nType==1 && strcmp(m_cifa[j]->szText,str))//是标识符
return true;
if(m_cifa[j+1]->nType==32)//要是豆号,继续
continue;
if(m_cifa[j+1]->nType==30)//碰到分号,一条定义语句结束
break;
if(!(m_cifa[j]->nType==14))//不再是定义语句
return false;
}
}
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -