实验一、词法分析实验

实验一、词法分析实验

专业:商业软件工程   姓名:王晓才  学号:201506110092

一、        实验目的

(1)    理解词法分析在编译程序中的作用。

(2)    加深对有穷自动机模型的理解。

(3)    掌握词法分析程序的实现方法。

(4)    用C语言对一个简单语言的子集编制一个一遍扫锚的编译理解,掌握编译程序的实现方法和技术。

 

二、        实验内容和要求

1,待分析的简单语言的词法。

2,各种单词符号对应的种别码。

3,词法分析程序的功能(输入,输出)。

 

三、        实验方法、步骤及结果测试

 

  1. 1.      源程序名:词法分析.cpp
#include<stdio.h>

#include<string.h>

#include<stdlib.h>

char TOken[10];//分开进行比较

char ch;

/*char rwtab[6]={"begin","if","then","while","do","end"};*/

char r1[]={"auto"};

char r2[]={"break"};

char r3[]={"case"};

char r4[]={"char"};

char r5[]={"const"};

char r6[]={"continue"};

char r7[]={"default"};

char r8[]={"do"};

char r9[]={"double"};

char r10[]={"else"};

char r11[]={"enum"};

char r12[]={"extern"};

char r13[]={"float"};

char r14[]={"for"};

char r15[]={"goto"};

char r16[]={"if"};

char r17[]={"int"};

char r18[]={"long"};

char r19[]={"register"};

char r20[]={"return"};

char r21[]={"short"};

char r22[]={"signed"};

char r23[]={"sizeof"};

char r24[]={"static"};

char r25[]={"struct"};

char r26[]={"switch"};

char r27[]={"typedef"};

char r28[]={"union"};

char r29[]={"unsigned"};

char r30[]={"void"};

char r31[]={"volatile"};

char r32[]={"while"};

char r33[]={"end"};

char r34[]={"include"};

char r35[]={"stdio"};

char r36[]={"string"};

char r37[]={"main"};

char r38[]={"stdlib"};//这是我定义的

char A[10000];//输入的所有值

int syn,row;

int n,m,p,sum,j;

static int i = 0;

 

 

void scaner()

{

/*

共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else

 

 

*/

for(n=0;n<7;n++)

TOken[n]=0;//每次循环完就清零

ch=A[i];

while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过

{

i++;

ch=A[i];

}

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名

{

m=0;

while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一个变量名或者关键字,直到遇到空格为止

{

TOken[m]=ch;m++;

i++;ch=A[i];

}

TOken[m]='\0';

//将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2......

if(strcmp(TOken,r1)==0){syn=1;}

else if(strcmp(TOken,r2)==0){syn=2; }

else if(strcmp(TOken,r3)==0){syn=3;}

else if(strcmp(TOken,r4)==0){syn=4;}

else if(strcmp(TOken,r5)==0){syn=5;}

else if(strcmp(TOken,r6)==0){syn=6;}

else if(strcmp(TOken,r7)==0){syn=7;}

else if(strcmp(r8,TOken)==0){syn=8;}

else if(strcmp(r9,TOken)==0){syn=9;}

else if(strcmp(r10,TOken)==0){syn=10;}

else if(strcmp(r11,TOken)==0){syn=11;}

else if(strcmp(r12,TOken)==0){syn=12;}

else if(strcmp(r13,TOken)==0){syn=13;}

else if(strcmp(r14,TOken)==0){syn=14;}

else if(strcmp(r15,TOken)==0){syn=15;}

else if(strcmp(r16,TOken)==0){syn=16;}

else if(strcmp(r17,TOken)==0){syn=17;}

else if(strcmp(r18,TOken)==0){syn=18;}

else if(strcmp(r19,TOken)==0){syn=19;}

else if(strcmp(r20,TOken)==0){syn=20;}

else if(strcmp(r21,TOken)==0){syn=21;}

else if(strcmp(r22,TOken)==0){syn=22;}

else if(strcmp(r23,TOken)==0){syn=23;}

else if(strcmp(r24,TOken)==0){syn=24;}

else if(strcmp(r25,TOken)==0){syn=25;}

else if(strcmp(r26,TOken)==0){syn=26;}

else if(strcmp(r27,TOken)==0){syn=27;}

else if(strcmp(r28,TOken)==0){syn=28;}

else if(strcmp(r29,TOken)==0){syn=29;}

else if(strcmp(r30,TOken)==0){syn=30;}

else if(strcmp(r31,TOken)==0){syn=31;}

else if(strcmp(r32,TOken)==0){syn=32;}

else if(strcmp(r33,TOken)==0){syn=33;}

else if(strcmp(r34,TOken)==0){syn=34;}

else if(strcmp(r35,TOken)==0){syn=35;}

else if(strcmp(r36,TOken)==0){syn=36;}

else if(strcmp(r37,TOken)==0){syn=37;}

else if(strcmp(r38,TOken)==0){syn=38;}

else{syn=100;} //变量名

}

else if((ch>='0'&&ch<='9')) //数字

{

sum=0;

while((ch>='0'&&ch<='9'))

{

sum=sum*10+ch-'0';//显示其数字sum

i++;

ch=A[i];

}

syn=40;

}

else switch(ch) //其他字符

{

case'<':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')//<>为22

{

syn=41;

TOken[m]=ch;m++;i++;

}

else

{

syn=46;

}

break;

case'>':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')

{

syn=42;

TOken[m]=ch;m++;i++;

}

else

{

syn=47;

}

break;

case':':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')

{

syn=44;

TOken[m]=ch;m++;i++;

}

else

{

syn=49;

}

break;

case'@':syn=0;TOken[0]=ch;i++;break;

case'=':syn=48;TOken[0]=ch;i++;break;

case'#':syn=50;TOken[0]=ch;i++;break;

case'+':syn=50;TOken[0]=ch;i++;break;

case'-':syn=51;TOken[0]=ch;i++;break;

case'*':syn=52;TOken[0]=ch;i++;break;

case'/':syn=53;TOken[0]=ch;i++;break;

case'(':syn=54;TOken[0]=ch;i++;break;

case')':syn=55;TOken[0]=ch;i++;break;

case'{':syn=56;TOken[0]=ch;i++;break;

case'}':syn=57;TOken[0]=ch;i++;break;

case';':syn=58;TOken[0]=ch;i++;break;

case'.':syn=59;TOken[0]=ch;i++;break;

case'\'':syn=60;TOken[0]=ch;i++;break;

case'\n':syn=-2;break;

default: syn=-1;break;

}

}

main()

{

row = 0 ;

p = 0 ;

printf("Please input string:(end of '@')\n");

do

{

scanf("%c",&ch);

A[p]=ch;

p++;

}//输入值到数组A【】中,以@结束

while(ch!='@');

do

{

scaner();//进入函数进行判定

switch(syn)

{

case 40: printf("(%d,%d)\n",syn,sum); break;//如果是40,那么就是数字

case 0: printf("(%d,%c)\n",syn,TOken[0]);break;//如果是0,那么是@ 结束

case -2: row=row++;break;

default: printf("(%d,%s)\n",syn,TOken);break;//否则,就是变量名、关键词

}

}

while (syn!=0);

}

 

 

  1. 2.      原理分析及流程图

主要总体设计问题。

(包括存储结构,主要算法,关键函数的实现等)

词法分析主程序示意图

  1. 3.      主要程序段及其解释:

实现主要功能的程序段,重要的是程序的注释解释。

 

void scaner()

{

/*

共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else

 

 

*/

for(n=0;n<7;n++)

TOken[n]=0;//每次循环完就清零

ch=A[i];

while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过

{

i++;

ch=A[i];

}

if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名

{

m=0;

while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一个变量名或者关键字,直到遇到空格为止

{

TOken[m]=ch;m++;

i++;ch=A[i];

}

TOken[m]='\0';

//将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2......

if(strcmp(TOken,r1)==0){syn=1;}

else if(strcmp(TOken,r2)==0){syn=2; }

else if(strcmp(TOken,r3)==0){syn=3;}

else if(strcmp(TOken,r4)==0){syn=4;}

else if(strcmp(TOken,r5)==0){syn=5;}

else if(strcmp(TOken,r6)==0){syn=6;}

else if(strcmp(TOken,r7)==0){syn=7;}

else if(strcmp(r8,TOken)==0){syn=8;}

else if(strcmp(r9,TOken)==0){syn=9;}

else if(strcmp(r10,TOken)==0){syn=10;}

else if(strcmp(r11,TOken)==0){syn=11;}

else if(strcmp(r12,TOken)==0){syn=12;}

else if(strcmp(r13,TOken)==0){syn=13;}

else if(strcmp(r14,TOken)==0){syn=14;}

else if(strcmp(r15,TOken)==0){syn=15;}

else if(strcmp(r16,TOken)==0){syn=16;}

else if(strcmp(r17,TOken)==0){syn=17;}

else if(strcmp(r18,TOken)==0){syn=18;}

else if(strcmp(r19,TOken)==0){syn=19;}

else if(strcmp(r20,TOken)==0){syn=20;}

else if(strcmp(r21,TOken)==0){syn=21;}

else if(strcmp(r22,TOken)==0){syn=22;}

else if(strcmp(r23,TOken)==0){syn=23;}

else if(strcmp(r24,TOken)==0){syn=24;}

else if(strcmp(r25,TOken)==0){syn=25;}

else if(strcmp(r26,TOken)==0){syn=26;}

else if(strcmp(r27,TOken)==0){syn=27;}

else if(strcmp(r28,TOken)==0){syn=28;}

else if(strcmp(r29,TOken)==0){syn=29;}

else if(strcmp(r30,TOken)==0){syn=30;}

else if(strcmp(r31,TOken)==0){syn=31;}

else if(strcmp(r32,TOken)==0){syn=32;}

else if(strcmp(r33,TOken)==0){syn=33;}

else if(strcmp(r34,TOken)==0){syn=34;}

else if(strcmp(r35,TOken)==0){syn=35;}

else if(strcmp(r36,TOken)==0){syn=36;}

else if(strcmp(r37,TOken)==0){syn=37;}

else if(strcmp(r38,TOken)==0){syn=38;}

else{syn=100;} //变量名

}

else if((ch>='0'&&ch<='9')) //数字

{

sum=0;

while((ch>='0'&&ch<='9'))

{

sum=sum*10+ch-'0';//显示其数字sum

i++;

ch=A[i];

}

syn=40;

}

else switch(ch) //其他字符

{

case'<':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')//<>为22

{

syn=41;

TOken[m]=ch;m++;i++;

}

else

{

syn=46;

}

break;

case'>':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')

{

syn=42;

TOken[m]=ch;m++;i++;

}

else

{

syn=47;

}

break;

case':':m=0;TOken[m]=ch;m++;

i++;ch=A[i];

if(ch=='=')

{

syn=44;

TOken[m]=ch;m++;i++;

}

else

{

syn=49;

}

break;

case'@':syn=0;TOken[0]=ch;i++;break;

case'=':syn=48;TOken[0]=ch;i++;break;

case'#':syn=50;TOken[0]=ch;i++;break;

case'+':syn=50;TOken[0]=ch;i++;break;

case'-':syn=51;TOken[0]=ch;i++;break;

case'*':syn=52;TOken[0]=ch;i++;break;

case'/':syn=53;TOken[0]=ch;i++;break;

case'(':syn=54;TOken[0]=ch;i++;break;

case')':syn=55;TOken[0]=ch;i++;break;

case'{':syn=56;TOken[0]=ch;i++;break;

case'}':syn=57;TOken[0]=ch;i++;break;

case';':syn=58;TOken[0]=ch;i++;break;

case'.':syn=59;TOken[0]=ch;i++;break;

case'\'':syn=60;TOken[0]=ch;i++;break;

case'\n':syn=-2;break;

default: syn=-1;break;

}
}

 

 4.      运行结果及分析

一般必须配运行结果截图,结果是否符合预期及其分析。

   (截图需根据实际,截取有代表性的测试例子)

 

四、        实验总结

心得体会,实验过程的难点问题及其解决的方法。

 

对于词法分析还不是很熟练,实验当中对于各个标识符的辨别有些难度,没办法准确输出,对于C语言的一些用法由于太久没用也显得有一些生疏,整体上来说有很大不足。要加强对编程的练习!!!

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/w092/p/5961127.html

附录c 编译程序实验 实验目的:用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。 语法分析 C2.1 实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析. C2.2 实验要求 利用C语言编制递归下降分析程序,并对简单语言进行语法分析. C2.2.1待分析的简单语言的语法 实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法. 实验要求 采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。 实验的输入和输出 输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串 begin a:=2+3*4;x:=(a+b)/c end# 输出的三地址指令如下: (1) t1=3*4 (2) t2=2+t1 (3) a=t2 (4) t3=a+b (5) t4=t3/c (6) x=t4 算法思想 1设置语义过程 (1) emit(char *result,char *arg1,char *op,char *ag2) 该函数功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: struct {char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20]; (2)char *newtemp() 该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…. Char *newtemp(void) { char *p; char m[8]; p=(char *)malloc(8); k++; itoa(k,m,10); strcpy(p+1,m); p[0]=’t’; return(p); } (2)主程序示意图如图c.10所示。 (2) 函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。 语义分析程序的C语言程序框架 int lrparser() { int schain=0; kk=0; if(syn=1) { 读下一个单词符号; schain=yucu; /调用语句串分析函数进行分析/ if(syn=6) { 读下一个单词符号; if(syn=0 && (kk==0)) 输出(“success”); } else { if(kk!=1 ) 输出 ‘缺end’ 错误;kk=1;} else{输出’begin’错误;kk=1;} } return(schain); int yucu() { int schain=0; schain=statement();/调用语句分析函数进行分析/ while(syn=26) {读下一个单词符号; schain=statement(); /调用语句分析函数进行分析/ } return(schain); } int statement() { char tt[8],eplace[8]; int schain=0; {switch(syn) {case 10: strcpy(tt,token); scanner(); if(syn=18) {读下一个单词符号; strcpy(eplace,expression()); emit(tt,eplace,””,””); schain=0; } else {输出’缺少赋值号’的错误;kk=1; } return(schain); break; } } char *expression(void) {char *tp,*ep2,*eplace,*tt; tp=(char *)malloc(12);/分配空间/ ep2=(char *)malloc(12); eplace=(char *)malloc(12); tt =(char )malloc(12); strcpy(eplace,term ());/调用term分析产生表达式计算的第一项eplace/ while(syn=13 or 14) { 操作符 tt= ‘+’或者‘—’; 读下一个单词符号; strcpy(ep2,term());/调用term分析产生表达式计算的第二项ep2/ strcpy(tp,newtemp());/调用newtemp产生临时变量tp存储计算结果/ emit(tp,eplace,tt,ep2);/生成四元式送入四元式表/ strcpy(eplace,tp); } return(eplace); } char *term(void)/仿照函数expression编写/ char *factor(void) {char *fplace; fplace=(char *)malloc(12); strcpy(fplace, “ ”); if(syn=10) {strcpy(fplace,,token);/将标识符token的值赋给fplace/ 读下一个单词符号; } else if(syn=11) {itoa(sum,fplace,10); 读下一个单词符号; } else if (syn=27) {读下一个单词符号; fplace=expression();/调用expression分析返回表达式的值/ if(syn=28) 读下一个单词符号; else{输出‘}’错误;kk=1; } } else{输出‘(’错误;kk=1; } return(fplace); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值