/* 目标代码生成过程gen */
/* 参数:x:要生成的一行代码的助记符 */
/* y, z:代码的两个操作数 */
/* 本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行 */
void gen(fct x,int y, int z)
{
if (cx > cxmax) /* 如果cx>cxmax表示当前生成的代码行号大于允许的最大代码行数 */
{
cout<<"program too long"; /* 输出"程序太长",退出 */
throw(99);
}
code[cx].f = x ;
code[cx].l = y ;
code[cx].a = z ;
++cx; /* 移动cx指针指向下一个空位 */
} /* gen */;
template<class T>
set<T> operator +(const set<T>& x, const set<T>& y)
{
set<T> z(x);
z.insert(y.begin(), y.end());
return z;
}
template<class T>
set<T>& operator += (set<T>& x, const set<T>& y)
{
x.insert(y.begin(), y.end());
return x;
}
/* 测试当前单词是否合法过程test */
/* 参数:s1:当语法分析进入或退出某一语法单元时当前单词符合应属于的集合 */
/* s2:在某一出错状态下,可恢复语法分析正常工作的补充单词集合 */
/* n:出错信息编号,当当前符号不属于合法的s1集合时发出的出错信息 */
void test(symset s1, const symset& s2, int n)
{
if (s1.find(sym)==s1.end()) /* 如果当前符号不在s1中 */
{
error(n); /* 发出n号错误 */
s1 += s2 ; /* 把s2集合补充进s1集合 */
while(s1.find(sym)==s1.end()) /* 通过循环找到下一个合法的符号,以恢复语法分析工作 */
getsym( );
}
}/* test */;
/* 登陆符号表过程enter */
/* 参数:k:欲登陆到符号表的符号类型 */
void enter(object k, const int& lev, int& tx, int &dx)
{ /* enter object into table */
++tx ; /* 符号表指针指向一个新的空位 */
memcpy(table[tx].name,id,10); /* name是符号的名字,对于标识符,这里就是标识符的名字 */
table[tx].kind = k ; /* 符号类型,可能是常量、变量或过程名 */
switch(k) /* 根据不同的类型进行不同的操作 */
{
case constant: /* 如果是常量名 */
{
if (num > amax) /* 在常量的数值大于允许的最大值的情况下 */
{
error(31); /* 抛出31号错误 */
num = 0 ; /* 实际登陆的数字以0代替 */
}
table[tx].val = num; /* 如是合法的数值,就登陆到符号表 */
break;
}
case variable: /* 如果是变量名 */
table[tx].level = lev ; /* 记下它所属的层次号 */
table[tx].adr = dx ; /* 记下它在当前层中的偏移量 */
++dx ; /* 偏移量自增一,为下一次做好准备 */
break;
case procedure: /* 如果要登陆的是过程名 */
table[tx].level = lev; /* 记录下这个过程所在层次 */
break;
}
} /* enter */;
/* 登录符号过程没有考虑到重复的定义的问题。如果出现重复定义,则以最后一次的定义为准。 */
/* 在符号表中查找指定符号所在位置的函数position */
/* 参数:id:要找的符号 */
/* 返回值:要找的符号在符号表中的位置,如果找不到就返回0 */
int position (alfa id,const int& tx)
{
int i;
/* find identifier in table */
memcpy(table[0].name,id,al) ; /* 先把id放入符号表0号位置 */
i = tx ; /* 从符号表中当前位置也即最后一个符号开始找 */
while(memcmp(table[i].name,id,al)!= 0) /* 如果当前的符号与要找的不一致 */
--i; /* 找前面一个 */
return i; /* 返回找到的位置号,如果没找到则一定正好为0 */
} /* position */;
template<class T>
bool in(const T val, const set<T>& s)
{
return s.find(val) != s.end();
}
编译原理程序设计实践(四)一些辅助函数
最新推荐文章于 2022-07-15 18:30:44 发布