词法分析器.docx
《词法分析器.docx》由会员分享,可在线阅读,更多相关《词法分析器.docx(14页珍藏版)》请在冰豆网上搜索。
词法分析器
中北大学软件学院
实验报告
专业
课程名称
学号
姓名
辅导教师成绩
实验日期
实验时间
1实验名称:
词法分析器的设计与实现
2、实验目的
(1)掌握C语言单词符号的划分、正规式、状态转换图及词法分析器的实现。
(2)掌握词法分析程序的作用。
3、实验要求
(1)对任给的一个C语言源程序,能够滤掉空格、回车换行符、tab键及注释。
(2)识别各类单词符号,如关键字、标识符、运算符、常数、界符,结果以二元式形式输出,并构造符号表。
(3)输出有词法错误的单词及所在行号。
(在此阶段只能识别有限的词法错误)
4、实验原理
根据扫描到的单词符号的第一个字符的种类,分别转到相应的程序进行处理。
这些程序的功能就是识别以相应字符开头的各类单词符号。
5、实验步骤
(1)根据C语言各类单词的正规式,构造能识别各类单词的状态转换图。
(2)根据状态转换图,构造识别各类单词的词法分析器。
6、状态转换图及词法分析程序
(1)标识符(ID)和整型常数(NUM)的正规式如下:
ID=_|letter(letter|digit)*
NUM=digitdigit*
其中标识符的状态转换图为:
其词法分析程序为:
if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_'))
{/*以字母开头*/
while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')||((ch>='0')&&(ch<='9')))
{
array[i++]=ch;
ch=fgetc(fpin);
}
word=(char*)malloc((i+1)*sizeof(char));
memcpy(word,array,i);
word[i]='\0';
is_id_key(word);
if(ch!
=EOF)
fseek(fpin,-1L,SEEK_CUR);
}
常数的状态转换图为:
其词法分析程序为:
elseif(ch>='0'&&ch<='9')
{/*以数字开头*/
while(ch>='0'&&ch<='9')
{
array[i++]=ch;
ch=fgetc(fpin);
}
word=(char*)malloc((i+1)*sizeof(char));
is_number(word,array,i);
word[i]='\0';
cs_manage(word);
if(ch!
=EOF)
fseek(fpin,-1L,SEEK_CUR);
}
(2)实验流程图
7、测试及结果
8、心得
实验日期
实验时间
1实验名称语法分析器的设计与实现
2、实验目的
掌握自上而下语法分析方法、自下而上语法分析方法
3、实验要求
(1)实验内容:
四选一
1设计及实现能够识别表达式的预测分析程序。
文法如下:
G[E]:
E->E+T|T
T->T*F|F
F->(E)|i
2设计及实现能够识别表达式的LR分析程序。
文法如下:
G[E]:
E->E+T|T
T->T*F|F
F->(E)|i
③设计及实现能够识别表达式的算符优先分析程序。
文法如下:
G[E]:
E->E+T|T
T->T*F|F
F->P↑F|P
P->(E)|i
④设计及实现计算表达式的计算器。
表达式中可包含+、-、*、/、(、)运算符。
(2)实验要求:
对已给的一个二元式形式表达式,能够检查有无语法错误。
并指定出错位置。
将表达式的语法树输出(或将语法分析过程输出)。
4、实验原理
根据自上而下和自下而上的语法分析思想实现语法分析程序。
5、实验步骤
(1)根据文法构造语法分析表。
(2)编写总控程序实现语法分析。
6、状态转换图及词法分析程序
include
#include
#definemax100
charex[max]; /*存储后缀表达式*/
voidtrans(){ /*将算术表达式转化为后缀表达式*/
charstr[max]; /*存储原算术表达式*/
charstack[max]; /*作为栈使用*/
charch;
intsum,i,j,t,top=0;
printf("*****************************************"n");
printf("*输入一个求值的表达式,以#结束。
*"n");
printf("******************************************"n");
printf("算数表达式:
");
i=0; /*获取用户输入的表达式*/
do{
i++;
scanf("%c",&str[i]);
}while(str[i]!
='#'&&i!
=max);
sum=i;
t=1;i=1;
ch=str[i];i++;
while(ch!
='#'){
switch(ch){
case'(':
/*判定为左括号*/
top++;stack[top]=ch;
break;
case')':
/*判定为右括号*/
while(stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top--;
break;
case'+':
/*判定为加减号*/
case'-':
while(top!
=0&&stack[top]!
='('){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'*':
/*判定为乘除号*/
case'/':
while(stack[top]=='*'||stack[top]=='/'){
ex[t]=stack[top];top--;t++;
}
top++;stack[top]=ch;
break;
case'':
break;
default:
while(ch>='0'&&ch<='9'){ /*判定为数字*/
ex[t]=ch;t++;
ch=str[i];i++;
}
i--;
ex[t]='#';t++;
}
ch=str[i];i++;
}
while(top!
=0){
ex[t]=stack[top];t++;top--;
}
ex[t]='#';
printf(""n"t原来表达式:
");
for(j=1;j printf("%c",str[j]);
printf(""n"t后缀表达式:
",ex);
for(j=1;j printf("%c",ex[j]);
}
voidcompvalue(){ /*计算后缀表达式的值*/
floatstack[max],d; /*作为栈使用*/
charch;
intt=1,top=0; /*t为ex下标,top为stack下标*/
ch=ex[t];t++;
while(ch!
='#'){
switch(ch){
case'+':
stack[top-1]=stack[top-1]+stack[top];
top--;
break;
case'-':
stack[top-1]=stack[top-1]-stack[top];
top--;
break;
case'*':
stack[top-1]=stack[top-1]*stack[top];
top--;
break;
case'/':
if(stack[top]!
=0)
stack[top-1]=stack[top-1]/stack[top];
else{
printf(""n"t除零错误!
"n");
exit(0); /*异常退出*/
}
top--;
break;
default:
d=0;
while(ch>='0'&&ch<='9'){
d=10*d+ch-'0'; /*将数字字符转化为对应的数值*/
ch=ex[t];t++;
}
top++;
stack[top]=d;
}
ch=ex[t];t++;
}
printf(""n"t计算结果:
%g"n",stack[top]);
}
main(){
trans();
compvalue();
}
7、测试及结果
8、心得