📄 func.cpp
字号:
/************ 该代码文件所包含的头文件 **************/
#include "globals.h" /* 该头文件globals.h定义了全局类与变量 */
#include "stdio.h"
#include "string.h"
#include "ctype.h" /* 用到了该库中的isalnum,isalpha,isdigit函数 */
#include "math.h" /* 用到了这个库里的取模运算 */
#include "func.h"
#include "compiler.h"
#include "iostream.h"
int Level=-1; /*scope栈的层数*/
TypeIR * intPtr = NULL; /*该指针一直指向整数类型的内部表示*/
TypeIR * charPtr = NULL; /*该指针一直指向字符类型的内部表示*/
TypeIR * boolPtr = NULL; /*该指针一直指向布尔类型的内部表示*/
/*记录当前层的displayOff*/
int savedOff = 0;
/*保存主程序的display表的偏移*/
int StoreNoff ;
/*=============词法分析部分=============*/
/*******************************************************************/
/* 函数名 getNextChar */
/* 功 能 取得下一非空字符函数 */
/* 说 明 该函数从输入缓冲区lineBuf中取得下一个非空字符 */
/* 如果lineBuf中的字串已经读完,则从源代码文件中读入一新行 */
/*******************************************************************/
int scanner::getNextChar(FILE* source)
{
/* 当前代码输入行缓冲器lineBuf已经耗尽 */
if (!(linepos < bufsize))
{
/* 源代码行号lineno加1 */
lineno++;
/* 从源文件source中读入BUFLEN-2(254)个字符到行缓冲区lineBuf中 *
* fgets在的lineBuf末尾保留换行符.并在末尾加了一个NULL字符表示结束 */
if (fgets(lineBuf,BUFLEN-1,source))
{
/* 如果源文件追踪标志EchoSource为TRUE *
* 将源程序行号lineno及行内容lineBuf在词法扫描时写入列表文件listing */
//if (EchoSource) fprintf(listing,"%4d: %s",lineno,lineBuf);
/* 取得当前输入源代码行的实际长度,送给变量bufsize */
bufsize = strlen(lineBuf);
/* 输入行缓冲区lineBuf中当前字符位置linepos指向lineBuf开始位置 */
linepos = 0;
/* 取得输入行缓冲区lineBuf中下一字符 */
return lineBuf[linepos++];
}
else
{
/* 未能成功读入新的代码行,fget函数返回值为NULL *
* 已经到源代码文件末尾,设置EOF_flag标志为TRUE */
EOF_flag = TRUE;
/* 函数返回EOF */
return EOF;
}
}
/* 行输入缓冲区lineBuf中字符还未读完,直接取其中下一字符,函数返回所取字符 */
else return lineBuf[linepos++];
}
/********************************************************/
/* 函数名 ungetNextChar */
/* 功 能 字符回退函数 */
/* 说 明 该过程在行输入缓冲区lineBuf中回退一个字符 */
/* 用于超前读字符后不匹配时候的回退 */
/********************************************************/
void scanner::ungetNextChar(void)
{
/* 如果EOF_flag标志为FALSE,不是处于源文件末尾 *
* 输入行缓冲区lineBuf中当前字符位置linepos减1 */
if (!EOF_flag) linepos-- ;
}
/**************************************************************/
/* 函数名 reservedLookup */
/* 功 能 保留字查找函数 */
/* 说 明 使用线性查找,查看一个标识符是否是保留字 */
/* 标识符如果在保留字表中则返回相应单词,否则返回单词ID */
/**************************************************************/
LexType scanner::reservedLookup (char * s)
{
int i;
/* 在保留字表中查找,MAXRESERVED已经定义为8,为保留字数 */
for (i=0;i<MAXRESERVED;i++)
/* 线性查保留字表,察看函数参数s指定标识符是否在表中 *
* 当两字符串匹配的时候,函数strcmp返回值为0(FALSE) */
if (!strcmp(s,reservedWords[i].str))
/* 字符串s与保留字表中某一表项匹配,函数返回对应保留字单词 */
return reservedWords[i].tok;
/* 字符串s未在保留字表中找到,函数返回标识符单词ID */
return ID;
}
/*=============语法分析部分=============*/
TokenType Syntax::getToken()
{
return token;
}
char * Syntax::getTemp_name()
{
return temp_name;
}
int Syntax::getLine0()
{
return line0;
}
void Syntax::setCurrentP(ChainNodeType * tokenl)
{
currentP=tokenl;
}
/********************************************************************/
/* 函数名 syntaxError */
/* 功 能 语法错误处理函数 */
/* 说 明 将函数参数message指定的错误信息格式化写入列表文件listing */
/* 设置错误追踪标志Error为TRUE */
/********************************************************************/
void Syntax::syntaxError(char * message)
{
cout<<" error : "<<endl;
cout<<"Syntax error at line"<<token.lineshow<<":"<<message<<endl;
Error = TRUE;
}
/********************************************************************/
/* 函数名 match */
/* 功 能 终极符匹配处理函数 */
/* 说 明 函数参数expected给定期望单词符号与当前单词符号token相匹配 */
/* 如果不匹配,则报非期望单词语法错误 */
/********************************************************************/
void Syntax::match(LexType expected)
{
if (token.Lex == expected)
{
ReadNextToken();
line0 = token.lineshow;
}
else
{
syntaxError("not match error ");
cout<<token.Sem<<endl;
ReadNextToken();
//exit(0);
}
}
/********************************************************/
/* 函数名 copyString */
/* 功 能 字符串复制函数 */
/* 说 明 该函数为已存在的字串分配内存单元,并将其复制 */
/********************************************************/
char * Syntax::copyString(char * s)
{ int n;
char * t;
/* 函数参数s所给字串为NULL(空), 函数返回NULL */
if (s==NULL) return NULL;
/* 函数参数s所给字串非空,计算字串s长度+1赋给临时变量n */
n = strlen(s)+1;
/* 动态分配内存单元,指定单元长度为n,t为指向该单元的指针 */
t = new char[n];
/* 单元指针t为NULL(空),未能成功分配 *
* 将出错信息及行号lineno写入列表文件listing */
if (t==NULL)
{
cout<<"Out of memory error at line "<<lineno<<endl;
Error = TRUE;
}
/* 调用库函数string.h,复制给定字串s到新字串单元t */
else strcpy(t,s);
/* 函数返回复制得到的新字串指针t */
return t;
}
/*****************************************************************/
/* 函数名 ReadNextToken */
/* 功 能 将文件tokenlist中的信息作为返回值 */
/* 一般,listing指向标准输出。 */
/* 说 明 返回值为TokenType类型,用于语法分析中 */
/*****************************************************************/
void Syntax::ReadNextToken()
{
token=currentP->Token;
currentP=currentP->nextToken;
}
/********************************************************
*********以下是创建语法树所用的各类节点的申请***********
********************************************************/
/********************************************************/
/* 函数名 newRootNode */
/* 功 能 创建语法树根节点函数 */
/* 说 明 该函数为语法树创建一个新的根结点 */
/* 并将语法树节点成员初始化 */
/********************************************************/
TreeNode * Syntax::newRootNode(void)
{
/* 在内存中动态申请分配单元,返回指向该单元的语法树结点类型指针t */
TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
/* 语法树节点指针t为NULL,未能成功分配内存单元 *
* 将出错信息及行号lineno写入列表文件listing */
if (t==NULL)
{
cout<<"Out of memory error at line"<<lineno<<endl;
Error = TRUE;
}
/* 语法树节点指针t不是NULL,成功分配内存单元 */
else
{
/* 初始化新语法树节点t各子节点child[i]为NULL */
for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
/* 初始化新语法树节点t兄弟节点sibling为NULL */
t->sibling = NULL;
/* 指定新语法树节点t成员:结点类型nodekind为语句类型ProK */
t->nodekind = ProK;
/* 指定新语法树节点t成员:源代码行号lineno为全局变量lineno */
t->lineno = lineno;
for(i=0;i<10;i++)
{
strcpy(t->name[i],"\0");
t->table[i] = NULL;
}
}
/* 函数返回语法树根节点指针t */
return t;
}
/********************************************************/
/* 函数名 newPheadNode */
/* 功 能 创建程序头类型语法树节点函数 */
/* 说 明 该函数为语法树创建一个新的程序头类型结点 */
/* 并将语法树节点成员初始化 */
/********************************************************/
TreeNode * Syntax::newPheadNode(void)
{
/* 在内存中动态申请分配单元,返回指向该单元的语法树结点类型指针t */
TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
/* 语法树节点指针t为NULL,未能成功分配内存单元 *
* 将出错信息及行号lineno写入列表文件listing */
if (t==NULL)
{
cout<<"Out of memory error at line"<<lineno<<endl;
Error = TRUE;
}
/* 语法树节点指针t不是NULL,成功分配内存单元 */
else {
/* 初始化新语法树节点t各子节点child[i]为NULL */
for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
/* 初始化新语法树节点t兄弟节点sibling为NULL */
t->sibling = NULL;
/* 指定新语法树节点t成员:结点类型nodekind为语句类型PheadK */
t->nodekind = PheadK;
/* 指定新语法树节点t成员:源代码行号lineno为全局变量lineno */
t->lineno = lineno;
t->idnum = 0;
for(i=0;i<10;i++)
{
strcpy(t->name[i],"\0");
t->table[i] = NULL;
}
}
/* 函数返回程序头类型语法树节点指针t */
return t;
}
/********************************************************/
/* 函数名 newDecANode */
/* 功 能 创建声明语法树节点函数,没有指明具体的节点声明 */
/* 类型,在语法树的第二层 */
/* 说 明 该函数为语法树创建一个新的结点 */
/* 并将语法树节点成员初始化 */
/********************************************************/
TreeNode * Syntax::newDecANode(NodeKind kind)
{
/* 在内存中动态申请分配单元,返回指向该单元的语法树结点类型指针t */
TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
/* 语法树节点指针t为NULL,未能成功分配内存单元 *
* 将出错信息及行号lineno写入列表文件listing */
if (t==NULL)
{
cout<<"Out of memory error at line"<<lineno<<endl;
Error = TRUE;
}
/* 语法树节点指针t不是NULL,成功分配内存单元 */
else {
/* 初始化新语法树节点t各子节点child[i]为NULL */
for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
/* 初始化新语法树节点t兄弟节点sibling为NULL */
t->sibling = NULL;
/* 指定新语法树节点t成员:结点类型nodekind为参数kind */
t->nodekind = kind;
/* 指定新语法树节点t成员:源代码行号lineno为全局变量lineno */
t->lineno = lineno;
for(i=0;i<10;i++)
{
strcpy(t->name[i],"\0");
t->table[i] = NULL;
}
}
/* 函数返回语法树根节点指针t */
return t;
}
/********************************************************/
/* 函数名 newTypeNode */
/* 功 能 类型标志语法树节点创建函数 */
/* 说 明 该函数为语法树创建一个新的类型标志结点, */
/* 表示在它之下的声明都为类型声明, */
/* 并将语法树节点的成员初始化 */
/********************************************************/
TreeNode * Syntax::newTypeNode()
{
/* 内存中动态申请分配单元,返回指向该单元的语法树节点类型指针t */
TreeNode * t = (TreeNode *) malloc(sizeof(TreeNode));
int i;
/* 语法树节点指针t为NULL,未能成功分配内存单元 *
* 将出错信息及行号lineno写入列表文件listing */
if (t==NULL)
cout<<"Out of memory error at line"<<lineno<<endl;
/* 语法树节点指针t不是NULL,内存单元已经成功分配 */
else {
/* 初始化新语法树节点t各子节点child[i]为NULL */
for (i=0;i<MAXCHILDREN;i++) t->child[i] = NULL;
/* 初始化新语法树节点t兄弟节点sibling为NULL(空) */
t->sibling = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -