编译原理程序设计实践(四)一些辅助函数
2013-03-13 21:46
686 查看
/* 目标代码生成过程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(); }
相关文章推荐
- 编译原理程序设计实践(五) 语法分析的相关函数
- 编译原理程序设计实践(二) 全局变量定义
- 编译原理程序设计实践(三) 错误处理和词法分析代码
- 编译原理程序设计实践(一) 项目描述
- 编译原理程序设计实践(六) 语句和子过程的处理代码
- 编译原理程序设计实践(七)解释器的相关代码
- 编译原理程序设计实践(八)— 主程序代码和makefile文件
- 编译原理程序设计实践(九) 编译和测试
- 程序设计语言——编译原理 第二章总结
- 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——3 计算4个函数
- 《C语言及程序设计》实践项目——函数起步
- 编译原理及实践(Compiler Construction Principles and Practice)——前言
- 第四周《C语言及程序设计》实践项目2 模块化程序设计及C语言中的函数
- 软考-程序设计语言基础(编译原理)
- 网络编程学习——一些辅助函数
- 编译原理及实践教材TINY编译器代码解析
- <<C++程序设计原理与实践>>粗读--chapter0 chapter1 chapter2
- fltk在Ubuntu Linux里面的搭建和测试--<<C++程序设计原理与实践>>Chapter12:一个显示模型 环境构建篇
- 正则表达式引擎的构建——基于编译原理DFA(龙书第三章)——3 计算4个函数
- 编译原理之学习 lua 1.1 笔记 (四) 多变量赋值和函数多返回值