编译原理课程设计报告
一、 设计概述(设计目的、环境、要求)
1、 设计目的
本次课程设计的目的是通过使用一个通用的能够自动根据正规表达式生成词法分析程序的工具程序设计一个简单语言的词法分析器,使学生充分理解课程理论内容和工具软件的使用技巧,掌握所涉及的典型数据结构,算法及方法,为今后在大型软件系统实践中设计性能优良的软件系统打下基础。
2、 设计环境
实验环境为Windows操作系统下,词法分析使用的主要工具是flex。
3、 设计要求
使用Flex工具,实现Decaf语言词法分析工作,对Decaf语言编写的源程序从左至右逐个字符进行扫描,产生一个单词序列。
二、 实验步骤(包括基本程序的分析步骤、测试的例子)
1、编写程序的分析步骤
(1)根据pp2所提供的scanner.l文件修改我们所需的词法分析程序scanner.l。
/*
*scanner.l *
* Flex输入文件,生成scanner */ %{
#include
*Global variable: yylval *-----------------------
*全局变量,我们可以从yylval中获得每个token的属性。
*以后这个变量由bison/yacc自动生成,在这个实验里面,我们手动定义。 */
YYSTYPE yylval; /*
*Global variable: yylloc *-----------------------
*全局变量,我们可以从yylloc中获得每个token的位置属性。 *以后也由bison/yacc自动生成。
编译原理课程设计报告
*/
struct yyltype yylloc;
static int curLineNum, curColNum; static char curLine[512];
static void DoBeforeEachAction();
#define YY_USER_ACTION DoBeforeEachAction(); Hashtable hasht; %}
%option stack %s N C %x COPY /*
*在这里定义你的辅助定义和开始条件 */
decimal [0-9]
HEX_decimal ({decimal}|[a-fA-F])+ HEX_INTEGER 0[Xx]{HEX_decimal}+ INTEGER {decimal}+
EXPONENT [Ee][-+]{INTEGER}
DOUBLE ({INTEGER}(\BEG_STRING (\\\
STRING ({BEG_STRING}\\\
IDENTIFIER ([a-zA-Z][a-zA-Z0-9_]*) OPERATOR [+\\-*/%=<>\\\\,.;!(){}\\[\\]] BEG_COMMENT (\END_COMMENT (\
SINGLE_COMMENT (\WHITE [ \\t]* /*
*以下是你的识别规则(patten&action)。
* 注意空格问题和括号\\引号匹配问题,一旦出错很难查出。 */
%%
yy_pop_state(); yyless(0); }
<*>\\n { curLineNum++; curColNum = 1;
if (YYSTATE != COPY) yy_push_state(COPY); }
{WHITE} { /* ignore space & tabs in normal or comment */ } /* -------------------- Comments ----------------------------- */ {BEG_COMMENT} { yy_push_state(C); }
\ return 0; }
编译原理课程设计报告
/* -------------------- Operators ----------------------------- */
/* -------------------- Constants ------------------------------ */
\
\ /* -------------------- Identifiers --------------------------- */
Declaration *temp;
if((temp=hasht.st_lookup(strdup(yytext)))==NULL) {
temp=new Declaration(yytext,yylloc.first_line,1); hasht.st_insert(*temp); } else {
编译原理课程设计报告
temp->IncrementOccurrences(); }
yylval.decl=temp; return T_Identifier;}
/* -------------------- Default rule (error) -------------------- */
void yyerror(char *msg) {
ReportError(&yylloc, \}
void Inityylex() {
BEGIN(N); // Start in Normal state
yy_push_state(COPY); // but copy first line at start curLineNum = 1; curColNum = 1; }
int yywrap() {
return (1); }
static void DoBeforeEachAction() {
yylloc.first_line = curLineNum; yylloc.first_column = curColNum;
yylloc.last_column = curColNum + yyleng - 1; curColNum += yyleng; }
const char *GetLineNumbered(int num) {
return (num == curLineNum) ? curLine : NULL; }
(2)根据pp1所提供的SYMTAB.C和SYMTAB.H文件修改我们所需要的哈希表的
头文件hashtable.h和实现哈希表的程序hashtable.cpp
①由于在数据结构方面为了实现很方便的进行查找,插入,删除等操作。于是把它的数据结构设计成一哈稀表结构,哈稀表的查找,插入等操作是快速的。所设计的哈稀结构符号表结构如下:
编译原理课程设计报告
②对标识符的处理
查找,返回对象指针 Y 找到否? N 出现次数+1 生成一个新的对象然后插入 将数据赋值给yylva.decl
③程序
《hashtable.cpp》 /*
Hashtable.cpp:
add your code below: */
#include
#include \#include \
/* SHIFT is the power of two used as multiplier in hash function */ #define SHIFT 4
int Hashtable::hash ( const char * key ) { int temp = 0; int i = 0;
while (key[i] != '\\0')
{ temp = ((temp << SHIFT) + key[i]) % SIZE; ++i; }
return temp; }
void Hashtable::st_insert( Declaration declation) { int h =hash(declation.GetName()); LineList l = hashTable[h];
while ((l != NULL) && (strcmp(declation.GetName(),l->declation.GetName()) != 0))
l = l->next; if (l == NULL)