📄 scan.cpp
字号:
// scan.cpp: implementation of the scan class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "scanner1.h"
#include "scan.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define INDEX 110 //表示标识符
#define CARCTER 111 //表示字符型常数
#define INTEN 112 //表示整型常数
#define REAL 113 //表示实型常数
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
scan::scan()
{
//初始化参数
row=0;
col=0;
p_wt=0;
m_st.point=0;
strtoken=_T("");
errnum=0;
memset(this->m_st.strtabe,0,1000);
wordtablenum=0;
//初始化符号表
for(int i=0;i<100;i++)
m_wt[i].start=0;
}
scan::~scan()
{
}
/*********************************************************************/
//函数说明:scan总控。得到传来的一行信息开始扫描
//参数说明:s-传来的一行信息,row-当前是第几行,count-这一行的字符个数
//返回值:分析后得到的token、错误信息、符号表
/*********************************************************************/
CString scan::Analyze(CString s,int row,int count)//scan总控
{
col=0; //列计数器初始化
memset(this->buf,0,100);
strcat(buf,s);
err=_T("");
char ch;
this->row=row;//行计数器初始化
this->count=count;
//扫描每一个字符
for (int i=0;i < count;i++)
{
ch=buf[i];
//开始判断
Sort(ch);
if (i<=col) //如果后面的字符已经处理,列计数器后移动
{
i=col;
col++;
}
if (col==count)//如果当前行已经处理完,就返回处理。
break;
}
return this->err;
}
/*********************************************************************/
//函数说明:扫描下一个字符
//参数说明:无
//返回值:返回下一个字符
/*********************************************************************/
char scan::ScanNextChar()
{
col++; //列计数器后移
char c;
if(col < count) //当前行还有字符,就取当前字符
{
c = buf[col];
}
else
{
c = '\n';
}
return c;
}
/*********************************************************************/
//函数说明://分类处理字符
//参数说明:s-传来的一行信息,row-当前是第几行,count-这一行的字符个数
//返回值:分析后得到的token、错误信息、符号表
/*********************************************************************/
void scan::Sort(char ch)
{
//如果是空格就跳过
bool flag=true;
do{
if (ch==' ')
ch = ScanNextChar();
if (ch !=' ')
flag=false;
}while(flag);
//识别标识符
if (IsLetter(ch))
Recogid(ch);
//处理注释及界限符/
else if (ch=='/')
Handlecom(ch);
//识别数字常数
else if (IsNumber(ch))
Recogdig(ch);
//识别字符常数
else if (ch == 39)
Recogstr(ch);
//识别各种界符
else if (IsIdent(ch))
Recogdel(ch);
//处理错误的符号
else Error(ch);
}
/*********************************************************************/
//函数说明:处理注释
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Handlecom(char ch)
{
bool flag = false; //注释完成的标志
char c = ScanNextChar();
//是/号就返回除号的Token
if(c != '*')
{
col--;
AddToken("/",46,0);
return;
}
c = ScanNextChar();
//删除注释信息
while(col < count)
{
char temp = c;
c = ScanNextChar();
if(temp=='*' && c=='/')//注释结束
{
flag = true; //注释完成标志
break;
}
}
if(!flag)//注释不正确,就提示注释错误
{
char buffer[20]="";
err+="(";
err+=_itoa( row+1, buffer, 10 );
err+=",";
err+=_itoa( col+1, buffer, 10 );
err+=")";
err+="\t错误类型:";
err+="未知注释!\r\n";
errnum++;
}
}
/*********************************************************************/
//函数说明:识别标识符
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Recogid(char ch)
{
CString word=_T("");
word+=ch;
//如果是正确的字符就连接成单词
do
{
ch=ScanNextChar();
if (IsLetter(ch)|| IsNumber(ch))
word+=ch;
} while (IsLetter(ch) || IsNumber(ch));
col--;
int token=0;
unsigned entry=0;
if(IsKeyword(word,token)) //如果是关键字
AddToken(word,token+1,0);
else //不是关键字,就查找符号表
{
LookUp(word,INDEX,entry); //查询符号表
AddToken(word,33,entry);
}
}
/*********************************************************************/
//函数说明:识别数字常数
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
void scan::Recogdig(char ch)
{
bool IsInt = true; //是否是整常数的标志
char array[100];
memset(array,0,100);
array[0] = ch;
int i = 1;
do
{
ch = ScanNextChar();
//是实数
if(ch == '.'&& IsInt)
{
array[i] = '.';
i++;
IsInt = false; //不是整常数,是实常数
}
else if(IsNumber(ch))//如果是数字就连接起来
{
array[i] = ch;
i++;
}
else
{
//数字常数结束
CString s=_T("");
unsigned p=0;
//整常数
if(IsInt)
{
s.Format("%s",array);
LookUp(s,INTEN,p);//查找符号表,返回地址
AddToken(s,34,p);//加入相应的Token
}
//实常数
else
{
s.Format("%s",array);
LookUp(s,REAL,p);//查找符号表,返回地址
AddToken(s,35,p);//加入相应的Token
}
col--;
break;
}
} while(1);
}
/*********************************************************************/
//函数说明:得到传来的一行信息开始扫描
//参数说明:c-待处理的一个字符
//返回值:无
/*********************************************************************/
//识别字符常数
void scan::Recogstr(char c)
{
char array[100];
int i = 0;
unsigned p=0;
char ch = ScanNextChar();
//字符没有完
while(ch != 39 && col < count)
{
array[i] = ch;
ch = ScanNextChar();
i++;
}
//在遇到'''号,字符完了
if(ch == 39)
{
array[i] = '\0';
CString s=_T("");
s.Format("%s",array);
LookUp(s,CARCTER,p);
AddToken(s,36,p);
}
//报错
else
{
char buffer[20]="";
err+="(";
err+=_itoa( row+1, buffer, 10 );
err+=",";
err+=_itoa( col+1, buffer, 10 );
err+=")";
err+="\t错误类型:";
err+="缺少单引号!\r\n";
errnum++;
}
}
/*********************************************************************/
//函数说明:得到传来的一行信息开始扫描
//参数说明:ch-待处理的一个字符
//返回值:无
/*********************************************************************/
//识别各种界符
void scan::Recogdel(char ch)
{
switch(ch)
{
case '<':
{
char c = ScanNextChar();
//加入<=
if(c == '=')
{
AddToken("<=",51,0);
}
//加入<>
else if(c == '>')
{
AddToken("<>",52,0);
}
//加入<
else
{
col--;
AddToken("<",50,0);
}
}
break;
case '>':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -