编译原理的实验报告一

实验一 词法分析程序实验

专业 商软2班   姓名 黄仲浩  学号 201506110166

一、 实验目的

     编制一个词法分析程序。

 

二、 实验内容和要求

     输入:源程序字符串

     输出:二元组(种别,单词符号本身)。

 

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

  1. 源程序名:bianyiyuanli.c

可执行程序名:bianyiyuanli.exe

  1. 原理分析及流程图

     通过一些for循环和while循环进行一个个的翻译。

     源程序如下:

#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();

int 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);

}

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';

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

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;

}

}

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

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

do

{

scanf("%c",&ch);

A[p]=ch;

p++;

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

while(ch!='@');

这是一个输入的程序段,主要的功能是为了将用户想要编译的字符输入到A[]中,方便后面进行一个个的排序。

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);

}

这是一个循环和一个输出函数,scaner()函数是为了将数字,变量名,关键字分辨出来并且以种别码进行分类写出,后面的输出就是根据syn的数字来确定输出的环境。

  1. 运行结果及分析

 

 

四、 实验总结

刚开始完全不了解这个编译原理的意思,只有自己去网上寻找和询问同学,但是在懂明白后发现这个编译原理是很有趣的,慢慢的去学会了,然后在自己去创建多个种别类。

 

 

 

 

 

 

 

posted @ 2016-10-13 22:06  166黄仲浩  阅读(1467)  评论(4编辑  收藏  举报