📄 ccifafenxi.cpp
字号:
//CCiFaFenXi.cpp
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <iostream.h>
#include "CFenCi.h"
CFenXi::CFenXi()
{
init();
for(int i=0;i<10000;i++)
m_cifa[i] = NULL;
}
/*================================================================
* 函数名: ShengMing
* 功能描述: 声明 (protected)
* 返回值: void
================================================================*/
bool CFenXi::ShengMing()
{
switch (m_cifa[m_nCur]->nType)
{
case 14: //Interger
case 15: //real
if (!BianliangShengMing()) //变量声明
return false;
break;
case 5: //procedure
if (!GuoChengShengMing()) //过程声明
return false;
break;
default:
m_nErrNo=11; //缺少声明(integer,real,procedure)
m_nErrAddr=m_nCur;
return false;
}
return true;
}
/****************************************
* 函数名: BianliangShengMing
* 功能描述: 变量声明 (protected)
* 返回值: void
* 示例: Integer x,y,z;
******************************************/
bool CFenXi::BianliangShengMing()
{
switch(m_cifa[m_nCur]->nType)
{
case 14: //Interger
case 15: //real
break;
default:
m_nErrNo=12; //缺少变量类型 integer 或 real!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if( m_cifa[m_nCur]->nType !=1)
{
m_nErrNo=14; //变量声明后缺少标识符!
m_nErrAddr=m_nCur;
return false;
}
/* if(!IsRedefine(m_cifa[m_nCur]->szText))
{
m_nErrNo=41;//变量重复定义
return false;
}
*/
m_nCur++;
while (m_cifa[m_nCur]->nType==32) //32 , 分析用逗号隔开的连续声明的几个变量
{
m_nCur++;
if( m_cifa[m_nCur]->nType !=1) //id
{
m_nErrNo=14; //变量声明后缺少标识符
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
}
return true;
}
/***************************************
*函数名:CiFaFenXi
*所属类:CFenXi
*功能:从输入串分离出一个个的单词
****************************************/
bool CFenXi::CiFaFenXi()
{
bool flag=true;
char token[20];
int k,v;
int line=0;//行序指示标量
for (int i=0;i<m_n;i++) //当第2次调用该函数时,就要释放前1次的资源
{
delete m_cifa[i];
}
int n=0; //用于指示当前的字符
m_n=0; //词法结果单词的个数
//过滤不显示的字符
while(m_str[n])
{
while (1)
{
if (m_str[n]=='\r')//过滤回车符
n++;
else if(m_str[n]=='\n')//过滤换行符
{
line++;
n++;
}
else if(m_str[n]=='\t')//过滤制表符
n++;
else if(m_str[n]==' ')//过滤空格
n++;
else
break;
}
//识别可显示字符
if (isalpha(m_str[n])) //字母
{
k=0;
while(1)
{
if(k<19) //标志符的长度为20
token[k++]=m_str[n++];
else //把超过20的部分过滤掉
n++;
if (!isalnum(m_str[n])) //如果不是数字或字母就退出
break;
}
token[k]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc, "Reserved word:");
m_cifa[m_n]->nAddr=n-k;
m_cifa[m_n]->nLineNo = line;
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);
strcpy(m_cifa[m_n]->szDesc, "ID,name=");
m_cifa[m_n]->nAddr=n-k;
m_cifa[m_n]->nLineNo = line;
m_n++;
}
}
else if (isdigit(m_str[n])) //数字
{
k=0;
while (1)
{
if (k<=8)
token[k++]=m_str[n++];
else
{
n++;//过滤长度数字串中超过8的部分
}
if (!isdigit(m_str[n]))
break;
}
token[k]=0;
v=atoi(token);
{
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);
strcpy(m_cifa[m_n]->szDesc,"NUM,val=");
m_cifa[m_n]->nAddr=n-k;
m_cifa[m_n]->nLineNo = line;
m_n++;
}
}
else
switch (m_str[n]) //其他符号
{
case '+':
case '-':
case '*':
case ';':
case '~':
case '&':
case '.':
case ',':
case '(':
case ')':
token[0]=m_str[n];
token[1]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc," ");
m_cifa[m_n]->nLineNo = line;
m_cifa[m_n]->nAddr=n;
m_n++;
n++;
break;
case '\0':
n++;
break;
case '#':
nLength = m_n;
return true;
case '<':
switch (m_str[ n+1])
{
case '=':
token[0]=m_str[n];
token[1]=m_str[n+1];
token[2]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"小于等于");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
m_n++;
n++;
n++;
break;
case '>':
token[0]=m_str[n];
token[1]=m_str[n+1];
token[2]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"不等于");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
m_n++;
n++;
n++;
break;
default:
token[0]=m_str[n];
token[1]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"小于");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
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=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"大于等于");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
m_n++;
n++;
n++;
break;
default:
token[0]=m_str[n];
token[1]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"大于");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
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=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"赋值运算符");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
m_n++;
n++;
n++;
break;
default:
token[0]=m_str[n];
token[1]=0;
v=FinKW(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);
strcpy(m_cifa[m_n]->szDesc,"类型说明符号");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
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);
strcpy(m_cifa[m_n]->szDesc,"ddd");
m_cifa[m_n]->nAddr=n;
m_cifa[m_n]->nLineNo = line;
m_n++;
n++;
flag=false;
}
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,"");
strcpy(m_cifa[m_n]->szDesc,"错误");
m_cifa[m_n]->nAddr=n-1;
m_cifa[m_n]->nLineNo = line;
m_n++;
break;
}
}
return flag;
}
/*********************************************************
* 函数名: FinKW(char * a)
* 功能描述: 在关键字表中查找 (protected)
* 返回值: int (如果找到返回在表中的位置,否则返回0)
**********************************************************/
int CFenXi::FinKW(char * a)
{
for (int i=0;i<50;i++)
if (!::stricmp(m_kw[i],a)) //找到
return i;
return 0; //未找到
}
/*****************************************
* 函数名: GuoChengYuJu
* 功能描述: 过程语句 (protected)
* 返回值: void
* 示例: Call ab(x,y,z);
******************************************/
bool CFenXi::GuoChengYuJu()
{
if(m_cifa[m_nCur]->nType != 13) //call,这句不可能执行
{
m_nErrNo=26; //缺少保留字“ call ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if(m_cifa[m_nCur]->nType != 1)
{
m_nErrNo=27; //缺少被调过程名标识符!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if(m_cifa[m_nCur]->nType != 33 )
return true;
if (!ShiCan()) //表达式
return false;
return true;
}
/********************************
* 函数名: ShiCan
* 功能描述: 实参表 (protected)
* 返回值: void
*示例: Call ab(x,y,z);
**********************************/
bool CFenXi::ShiCan()
{
if(m_cifa[m_nCur]->nType != 33 ) //(,这块不可能被执行
{
m_nErrNo=16; //缺少 “ ( ”符号!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!BiaoDaShi()) //表达式
return false;
while (m_cifa[m_nCur]->nType==32) //,
{
m_nCur++;
if (!BiaoDaShi())
return false;
}
if(m_cifa[m_nCur]->nType !=34 )//)
{
m_nErrNo=17; //缺少 “ ) ”符号
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
return true;
}
/********************************************
* 函数名: YuFaFenXi
* 功能描述: 语法分析 (public)
* 返回值: void
**********************************************/
bool CFenXi::YuFaFenXi()
{
// if (m_n==0)
// return; //尚未进行词法分析
m_nCur=0; //m_nCur用语指示词法分析结果表中单词的位置
if(!ChengXu()) //从 程序 开始
return false;
return true;
}
/******************************************
* 函数名: ChengXu
* 功能描述: 分析整个程序 (protected)
* 返回值: bool
* 示例:
Program abc;
这里是程序体
.
*******************************************/
bool CFenXi::ChengXu() //程序
{
if(m_cifa[m_nCur]->nType !=3)
{
m_nErrNo=3; //缺少关键字 program
m_nErrAddr=m_nCur;
return false;
}
m_nCur++; //分析下一个单词
if(m_cifa[m_nCur]->nType !=1) //标志符
{
m_nErrNo=4; //program 后缺少标识符!
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;
if(m_cifa[m_nCur]->nType != 31) //'.' (程序的最后一个符号)
{
m_nErrNo=6; //缺少程序结束符.
m_nErrAddr=m_nCur;
return false;
}
return true;
}
/*************************************************
* 函数名: ShengMingChuan
* 功能描述: 声明串 用;隔开的多个声明(protected)
* 返回值: void
**************************************************/
bool CFenXi::ShengMingChuan()
{
if (!ShengMing())
return false;
while (m_cifa[m_nCur]->nType==30 && m_cifa[m_nCur+1]->nType!=6) //是; 不是begin
{
m_nCur++;
if (!ShengMing()) //递归调用
return false;
}
return true;
}
/****************************************
* 函数名: ChengXuTi
* 功能描述: 分析程序体 (protected)
* 返回值: bool
* 示例:
***************************************/
bool CFenXi::ChengXuTi()
{
switch (m_cifa[m_nCur]->nType)
{
case 5: //procedure
case 14: //booleger
case 15: //real
if (!ShengMingChuan()) //声明串(用;隔开的多个变量或过程声明)
return false;
if(m_cifa[m_nCur]->nType !=30 ) //;
{
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;
}
if(m_cifa[m_nCur]->nType !=6) //begin
{
m_nErrNo=8; //缺少保留字“ begin ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
if (!YuJuChuan()) //语句串
{
return false;
}
//cout<<m_cifa[m_nCur]->szText<<endl;
//cout<<m_cifa[m_nCur+1]->szText<<endl;
//cout<<m_cifa[m_nCur+2]->szText<<endl;
if( m_cifa[m_nCur]->nType !=7) //end
{//cout<<m_cifa[m_nCur]->szText<<endl;
m_nErrNo=10; //缺少保留字“ end ”!
m_nErrAddr=m_nCur;
return false;
}
m_nCur++;
return true;
}
/*******************************************
* 函数名: GuanXiBiaoDaShi
* 功能描述: 关系表达式 (protected)
* 返回值: void
********************************************/
bool CFenXi::GuanXiBiaoDaShi()
{
if (!BiaoDaShi()) //表达式
return false;
if (!GuanXi()) //关系
return false;
if (!BiaoDaShi()) //表达式
return false;
return true;
}
/********************************************
* 函数名: GuanXi
* 功能描述: 关系 (protected)
* 返回值: void
*********************************************/
bool CFenXi::GuanXi()
{
switch (m_cifa[m_nCur]->nType)
{
case 23: //<
case 24: //<=
case 25: //>
case 26: //>=
case 27: //=
case 28: //<>
break;
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -