词法分析实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理实验一
姓名:朱彦荣
学号:
专业:软件工程2
实验题目:词法分析
完成语言:C/C++
上级系统:VC++6.0
日期:2015/11/7
词法分析
设计题目:手工设计c语言的词法分析器
(可以是c语言的子集)
设计内容:
处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。
设计目的:
了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。
结果要求:课程设计报告。
完成日期:第十五周提交报告
一.分析
要想手工设计词法分析器,实现C语言子集的识别,就要明白什么是词法
主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对整个源程序进行分解,分解成一个个单词,这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。以便为下面的语法分析和语义分析做准备。可以说词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);而语法的分析则是利用词法分析的结果作为输入来分析是否符合语法规则并且进行语法制导下的语义分析,最后产生四元组(中间代码),进行优化(可有可无)之后最终生成目标代码。可见词法分析是所有后续工作的基础,如果这一步出错,比如明明是‘<=’却被拆分成‘<’和‘=’就会对下文造成不可挽回的影响。因此,在进行词法分析的时候一定要定义好这五种符号的集合。下面是我构造的一个C语言子集。
第一类:标识符letter(letter | digit)* 无穷集
第二类:常数(digit)+ 无穷集
第三类:保留字(32)
auto break case char const continue
default do double else enum extern
float for goto if int long
register return short signed sizeof static
struct switch typedef union unsigned void
volatile while
第四类:界符‘/*’、‘//’、() { } [ ] " " ' 等
第五类:运算符<、<=、>、>=、=、+、-、*、/、^、等
对所有可数符号进行编码:
<$,0>
...
<+,33>
<-,34>
<*,35>
,36>
<<,37>
<<=,38>
<>,39>
<>=,40>
<==,42>
<;,44>
<(,45>
<),46>
<^,47>
<,,48>
<",49>
<',50>
<#,51>
<&,52>
<&&,53>
<|,54>
<||,55>
<%,56>
<~,57>
<<<,58>左移
<>>,59>右移
<[,60>
<],61>
<{,62>
<},63>
<\,64>
<.,65>
,66>
<:,67>
"[","]","{","}"
<常数99 ,数值>
<标识符100 ,标识符指针>
上述二元组中左边是单词的符号,右边为其种别码,其中常数和标识符有点特别,因为是无穷集合,因此常数用自身来表示,种别码为99,标识符用标识符符号表的指针表示(当然也可用自身显示,比较容易观察),种别码100。根据上述约定,一旦见到了种别码syn=63,就唯一确定了‘}’这个单词。
下面是一些变量的约定:
//全局变量,保留字表
static char reserveWord[32][20] = {
"auto", "break", "case", "char", "const", "continue",
"default", "do", "double", "else", "enum", "extern",
"float", "for", "goto", "if", "int", "long",
"struct", "switch", "typedef", "union", "unsigned", "void",
"volatile", "while"
};
//界符运算符表,根据需要可以自行增加
static char operatorOrDelimiter[36][10]={
"+","-","*","/","<","<=",">",">=","=","==",
"!=",";","(",")","^",",","\"","\'","#","&",
"&&","|","||","%","~","<<",">>","[","]","{",
"}","\\",".","\?",":","!"
};
static char IDentifierTbl[1000][50]={""};//标识符表
char resourceProject[10000];//输入的源程序存放处,最大可以存放10000个字符。
char token[20]={0};//每次扫描的时候存储已经扫描的结果。
int syn=-1;//syn即为种别码,约定‘$’的种别码为0,为整个源程序的结束符号一旦扫描到这个字符代表扫描结束
int pProject = 0;//源程序指针,始终指向当前源程序待扫描位置。
几个重要函数:
//查找保留字,若成功查找,则返回种别码
//否则返回-1,代表查找不成功,即为标识符
int searchReserve(char reserveWord[ ][20], char s[])
/*********************判断是否为字母********************/
bool IsLetter(char letter)
/*****************判断是否为数字************************/
bool IsDigit(char digit)
/********************编译预处理,取出无用的字符和注释**********************/
void filterResource(char r[],int pProject)
/****************************分析子程序,算法核心***********************/
void Scanner(int &syn,char resourceProject[],char token[],int &pProject)
下面说一下整个程序的流程:
1.词法分析程序打开源文件,读取文件内容,直至遇上’$’文件结束符,然后读取结束。
2.对读取的文件进行预处理,从头到尾进行扫描,去除//和/* */的内容,以及一些无
用的、影响程序执行的符号如换行符、回车符、制表符等。但是千万注意不要在这个时候去除空格,因为空格在词法分析中有用,比如说int i=3;这个语句,如果去除空格就变成了“inti=3”,这样就失去了程序的本意,因此不能在这个时候去除空格。3.选下面就要对源文件从头到尾进行扫描了,从头开始扫描,这个时候扫描程序首先要