词法分析实验
- 格式:doc
- 大小:35.50 KB
- 文档页数:2
词法分析程序实验报告篇一:词法分析器_实验报告词法分析器实验报告实验目的:设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。
实验要求:该程序要实现的是一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分界符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(一)实验内容(1)功能描述:对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。
而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。
(2)程序结构描述:函数调用格式:参数含义:String string;存放读入的字符串 String str; 存放暂时读入的字符串 char ch; 存放读入的字符 int rs 判断读入的文件是否为空 char []data 存放文件中的数据 int m;通过switch用来判断字符类型,函数之间的调用关系图:函数功能:Judgement()判断输入的字符并输出单词符号,返回值为空; getChar() 读取文件的,返回值为空;isLetter(char c) 判断读入的字符是否为字母的,返回值为Boolean类型; switch (m) 判断跳转输出返回值为空;isOperator(char c)判断是否为运算符的,返回值为Boolean类型; isKey(String string)判断是否为关键字的,返回值为Boolean类型; isDigit(char c) 判断读入的字符是否为数字的,返回值为Boolean类型。
(二)实验过程记录:本次实验出错3次,第一次无法输出双运算符,于是采用双重if条件句进行判断,此方法失败,出现了重复输出,继续修改if语句,仍没有成功。
然后就采用了直接方法调用解决此问题。
对于变量的判断,开始忘了考虑字母和数字组成的变量,结果让字母和数字分家了,不过改变if语句的条件,解决了此问题。
实验一:词法分析1、实验目的:设计、编制并调试一个词法分析程序,加深对词法分析程序的理解。
2、实验要求:(1)能识别关键字、运算符号、界符、标识符、数字(无符号整数、实数(4分)、科学计数法表示的数,能识别注释。
(5分))(2)要求建立一张关键字和种别码表(3)源程序从键盘输入(4分)、源程序以文件的形式输入(5分)#include<stdio.h>#include<string.h>#include<stdlib.h>int syn,p_input,p_token,kk;char ch;char input[100];char token[100]="";char buf[500]="";char* key_words[]={"main","while","do","if","else","for"};int expression();void m_getch();int letter();int digit();int compare();void c_token();void scaner();void main(){FILE *fin;char buffer[100];int size;if((fin=fopen("testin.txt","r"))==NULL){printf("Cannot open the file!\n");exit(-1);}fin=fopen("testin.txt","r");while(fgets(buffer,100,fin)!=NULL){strcat(input,buffer);}lrparser();printf("\npress # to exit:\n");scanf("%[^#]",input);fclose(fin);}int lrparser(){scaner();if(syn==1){scaner();if(syn==17)scaner();else printf("error\n");if(syn==18)scaner();else printf("error\n");if(syn==19)scaner();else printf("error\n");yucu();if((syn==20)&&(kk==0)){printf("Success\n");return 1;}else {if(kk!=1)printf("no end error\n");return 0;} }else {printf("no main error\n");return 0;}}int yucu(){statement();while (syn==29){scaner();statement();}return 1;}void scaner(){p_token=0;m_getch();while(ch==' '||ch==10)m_getch();if(letter()){while(letter()||digit()){c_token();m_getch();}p_input--;syn=compare();}else if(digit()){while(digit()){c_token();m_getch();}p_input--;syn=11;}else switch(ch){case '=': c_token();m_getch();if(ch=='='){syn=24;c_token();}else{p_input--;syn=21;}break;case '<': c_token();m_getch();if(ch=='='){syn=25;c_token();}else if(ch=='>'){syn=26;c_token();}else{ p_input--;syn=22;}break;case '>': c_token();m_getch();if(ch=='='){syn=27;c_token();}else{p_input--;syn=23;}break;case '+': syn=13;c_token();break;case '-': syn=14;c_token();break;case '*': syn=15;c_token();break;case '/': syn=16;c_token();break;case '(': syn=17;c_token();break;case ')': syn=18;c_token();break;case '{': syn=19;c_token();break;case '}': syn=20;c_token();break;case ';': syn=29;c_token();break;case '\0': syn=0;break;default : syn=-1;c_token();}}void m_getch(){ch=input[p_input];p_input++;}void c_token(){token[p_token]=ch;p_token++;token[p_token]='\0';}int compare(){int n;for(n=0;n<6;n++){if(strcmp(key_words[n],token)==0)return n+1;}return 10;}int letter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;else return 0;}int digit(){if(ch>='0'&&ch<='9')return 1;else return 0;}int expression(){term();while (syn==13||syn==14){scaner();term();}return 1;}int factor(){if(syn==10||syn==11)scaner();else if(syn==17){scaner();expression();if (syn==18){scaner();}else { printf("输入错误\n");kk=1;return 0;} }else {printf("输入表达式错误\n");kk=1;return 0;} return 1;}int term(){factor();while(syn==15||syn==16){scaner();factor();}return 1;}int statement(){if(syn==10){scaner();if (syn==21){scaner();expression();}else {printf("输入赋值错误\n");kk=1;} }else {printf("输入语句错误\n");kk=1;}return 1;}。
词法分析实验报告词法分析实验报告引言词法分析是自然语言处理中的一个重要环节,它负责将输入的文本分割成一个个的词语,并确定每个词语的词性。
本次实验旨在通过实现一个简单的词法分析器,来探索词法分析的原理和实践。
实验内容本次实验中,我们使用Python编程语言来实现词法分析器。
我们选取了一段简单的英文文本作为输入,以便更好地理解和演示词法分析的过程。
1. 文本预处理在进行词法分析之前,我们首先需要对输入文本进行预处理。
预处理的目的是去除文本中的标点符号、空格和其他无关的字符,以便更好地进行后续的分词操作。
2. 分词分词是词法分析的核心步骤之一。
在这个步骤中,我们将文本分割成一个个的词语。
常见的分词方法包括基于规则的分词和基于统计的分词。
在本次实验中,我们选择了基于规则的分词方法。
基于规则的分词方法通过事先定义一系列的分词规则来进行分词。
这些规则可以是基于语法的,也可以是基于词典的。
在实验中,我们使用了一个简单的基于词典的分词规则,即根据英文单词的常见前缀和后缀来进行分词。
3. 词性标注词性标注是词法分析的另一个重要步骤。
在这个步骤中,我们为每个词语确定其词性。
词性标注可以通过事先定义的规则和模型来进行。
在本次实验中,我们使用了一个简单的基于规则的词性标注方法。
基于规则的词性标注方法通过定义一系列的词性标注规则来进行词性标注。
这些规则可以是基于词法的,也可以是基于语法的。
在实验中,我们使用了一个简单的基于词法的词性标注规则,即根据英文单词的后缀来确定其词性。
实验结果经过实验,我们得到了输入文本的分词结果和词性标注结果。
分词结果如下:- I- love- natural- language- processing词性标注结果如下:- I (代词)- love (动词)- natural (形容词)- language (名词)- processing (名词)讨论与总结通过本次实验,我们深入了解了词法分析的原理和实践。
实验一词法分析一、实验目的通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码与单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验要求使用一符一种的分法关键字、运算符和分界符可以每一个均为一种标识符和常数仍然一类一种三、实验内容功能描述:1、待分析的简单语言的词法(1)关键字:begin if then while do end(2)运算符和界符:(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码图 1程序结构描述:符号界符等符号四、实验结果输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图3所示:图3输入private x:=9;if x>0 then x:=2*x+1/3; end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图4所示:图4显然,private是关键字,却被识别成了标示符,这是因为图1中没有定义private关键字的种别码,所以把private当成了标示符。
输入private x:=9;if x>0 then x:=2*x+1/3; @ end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图5所示图5显然,@没有在图一中定义种别,所以输出了“Error in row 1!”的报错信息。
实验2 词法分析(4学时)实验要求:1. TEST语言的单词符号有:标识符:字母打头,后接字母数字,识别出的标识符用ID标记。
保留字(它是标识符的子集):if,else,for,while,do,int,write,read,识别出的保留字直接用该保留字标记。
无符号整数:由数字组成,用NUM标记。
分界符:+、-、*、/、(、)、;、,>、<、{、}、!等单分界符,直接用单分界符标记。
>=、<=、!=、==等双字符分界符,直接用双分界符标记。
注释符:用/*….*/括起为了从源程序字符流中正确识别出各类单词符号,相邻的标识符、整数或保留字之间至少要用一个空格分开。
TEST语言的各类单词符号的正则文法规则如下:<ID>∷=<letter>|ID<letter>|ID<digit><NUM>∷=<digit>|NUM <digit><letter>∷= a|b|…|z|A|B|…|Z<digit>∷=1|2|…|9|0<singleword>∷=+|-|*|/|=|(|)|{|}|:|,|;|<|>|!<doubleword>∷=>=|<=|!=|==<commend_first>∷=/*<commend_last>∷=*/2、修改TESTscan()程序,添加其余符号的处理。
1、AAA.test内容:= + - * / < > ( ) [ ] { } ; : ' " , == >= <= !=if else for while do int read write 358 aaa输出BBB.test的内容为:if else for while do int read write 358 aaaif else for while do int read write NUM ID这部分实验要求同学理解单词符号。
教案首页实验指导:#include "safx.h"#include <sio.h>#include <slib.h>#include <sing.h>#include <ctype.h>#include <malloc.h>#include <ctype.h>#include <conio.h>#define NULL 0FILE *fp;char ch;char *keyword[8]={"do","begin","else","end","if","then","var","while"};char *operatornum[4]={"+ ","-","*","/"};char *comparison[6]={"<","<=","=",">",">=","<>"};char *interpunction[6]={",",";",":=",".","(",")"};////////////////////////////////////////////////////////////////////////////// ////////////bool search(char searchs[],int wordtype){int i;switch (wordtype){case 1:for(i=0;i<=7;i ){if(scmp(keyword[i],searchs)==0)return(ue);}case 2:{for(i=0;i<=3;i ){if(scmp(operatornum[i],searchs)==0)return(ue);}break;}case 3: for(i=0;i<=5;i ){if(scmp(comparison[i],searchs)==0)return(ue);}case 4: for(i=0;i<=5;i ){if(scmp(interpunction[i],searchs)==0)return(ue);}}return(false);}////////////////////////////////////////////////////////////////////////////// /////////////char letterprocess (char ch)//字母处理函数{int i=-1;char letter[20];while (isalnum(ch)!=0){letter[ i]=ch;ch=fgetc(fp);};letter[i 1]='\0';if (search(letter,1)){printf("<%s,->\n",letter);//scat(letter,"\n");//fputs('<' letter '>\n',outp);}else{printf("<indentifier,%s>\n",letter);//scat(letter,"\n");//fputs(letter,outp);}return(ch);}////////////////////////////////////////////////////////////////////////////// /////////////char numberprocess(char ch)//数字处理程序{int i=-1;char num[20];while (isdigit(ch)!=0){num[ i]=ch;ch=fgetc(fp);}if(isalpha(ch)!=0){while(isspace(ch)==0){num[ i]=ch;ch=fgetc(fp);}num[i 1]='\0';printf("错误!非法标识符:%s\n",num);goto u;}num[i 1]='\0';printf("<num,%s>\n",num);//scat(num,"\n");//fputs(num,outp);u: return(ch);}////////////////////////////////////////////////////////////////////////////// ////////////////char otherprocess(char ch){int i=-1;char other[20];if (isspace(ch)!=0){ch=fgetc(fp);goto u;}while ((isspace(ch)==0)&&(isalnum(ch)==0)){other[ i]=ch;ch=fgetc(fp);}other[i 1]='\0';if (search(other,2))printf("<relop,%s>\n",other);elseif (search(other,3))printf("<%s,->\n",other);elseif (search(other,4))printf("<%s,->\n",other);elseprintf("错误!非法字符:%s\n",other);u: return (ch);}////////////////////////////////////////////////////////////////////////////// ///////////////void main (){char s,c;printf("*********************词法分析器*************************\n");//outp=fopen("二元式表.txt","w");if ((fp=fopen("源程序.txt","r"))==NULL)printf("源程序无法打开!\n");else{s =fgetc(fp);while (s!=EOF){if (isalpha(s)!=0)s=letterprocess(s);else{if (isdigit(s)!=0)s=numberprocess(s);elses=otherprocess(s);}};printf("词法分析结束,谢谢使用!\n"); printf("点任意键退出!\n");}c=getch();}。
实验一词法分析一、实验目的:通过本实验理解词法分析的整个过程,处理对象和处理的结果,了解词法分析在整个编译过程中的作用。
二、实验学时:2学时。
三、实验内容根据给出的简单语言的词法构成规则和单词集合,编制词法分析程序,要求能用给定的简单语言书写的源程序进行词法分析,同时建立相应的符号表文件存放正确的单词。
输出分析结果于文件中,包括:(1)正确的单词符号及其单词种类的序对二元组。
具体输出形式为:二元组:(单词种类,单词内码值)单词种类见五。
四、实验方法构造识别单词集的自动机,编写程序实现。
五、实验的处理单词集六、处理程序例和处理结果例例1:源程序:main(){y=x-1;}处理结果:(26,"main")(1,"(")(2,")")(3,"{")(0,"y")(6,"=")(0,"x")(100,"-")(20,"1")(5,";")(4,")")例2:源程序main(){int a,b;b!=a-1;}处理结果:(26,"main")(1,"(")(2,")")(3,"{" })(21,”int”)(0,"a")(11,",")(0,"b")(5,”;”)(0,"b")(100,"! ")(6,"=")(0,"a")(100,"-")(30,"1")(5,”;”)(4,”}”)七、实验报告要求给出单词识别的状态转换图;带有注释(简单说明)的源程序。
编译原理词法分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验预期四、程序规定五、实验原理●程序流程图●判别浮点功能扩展流程图●状态转换图六、程序代码与浮点判别功能扩展七、测试用例●扩展功能测试用例;●普通功能测试用例八、输出结果九、实验心得一、实验内容:词法分析:1、识别简单语言的单词符号;2、识别关键字、标识符、数字、运算符等。
并扩展浮点识别功能。
二、实验目的调试词法分析程序,加深对词法分析原理的理解,掌握编写简单词法分析程序的一般步骤。
三、实验预期结果:经过调试源代码程序,程序能够成功运行编译,对输入的简单字符串,能够别关键字、标识符、数字、运算符等,并且给出单词符号的对应编码。
四、程序规定:1、关键字:"function","if","then","while","do","endfunc";2、算术运算符:”+”,”-”,”*”,”/”,”=”;3、关系运算符:"<" ">" "<=" ">=" "==" "!=";4、界符:"(" ")" ";" "#";5、标识符规定以字母开头,字母均为小写;6、空格和换行符跳过;7、单词对应编码:十、实验原理:输入串--------------------〉词法分析程序————————〉单词符号串输入:字符串以#结束。
输出:单词的二元组(syn,token/sum)程序流程图分析浮点数功能扩展部分流程图:shuzi()函数状态转换图六、程序代码:备注:红色字体部分为程序功能的功能扩展,使程序能够分析浮点数!我把浮点数的syn设置为80!/*词法分析源代码*/#include<stdio.h>#include<string.h>scaner();char prog[80],token[8];char ch;int syn,p,m,n,sum;char * rwtab[6]={"function","if","then","while","do","endfunc"}; int i=0,k,c,sumint,f;char fenshu[80],sum1[80];double sumf=0,fudian;int shuzi(){if(ch>='0' && ch<='9')syn=80;elsesyn=-2;return syn;}main(){p=0;printf("\n please input string :\n");do{scanf("%c",&ch);prog[++p]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){ case 11:printf("\n(%d,%d)",syn,sum);break;case -1:printf("\n error");break;case 80:printf("\n(%d,%f)",syn,fudian);break; default:printf("\n(%d,%s)",syn,token);}}while(syn!=0);}scaner(){for(n=0;n<8;n++)token[n]=NULL;//if(1+2!=3)ch=prog[++p];while(ch==' ' || ch=='\n')ch=prog[++p];//跳过空格if(ch>='a' && ch<='z'){m=0;while(ch>='a' && ch<='z' || ch>='0' && ch<='9') {token[m++]=ch;//token[0]=f,m=1ch=prog[++p];}token[m]='\0';ch=prog[--p];syn=10;for(n=0;n<6;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}elseif(ch>='0' && ch<='9'){c=p;k=0;do{ sum1[k]=ch;ch=prog[++c]; //ch取后一个数字k++;shuzi();//这个函数用来分析浮点数的整数部分是否已经输入到数组里f=syn;} while(f==80)if(ch=='.'){for(n=0;n<k;n++){sumint=sumint*10+sum1[n]-'0';} //计算整数部分i=0;do{ch=prog[++c];fenshu[i]=ch;i++;shuzi();//这个函数用来分析浮点数的小数部分是否已经输入到数组里} while(syn==80);sumf=0;for(k=i-2;k>=0;k--){sumf=sumf*0.1+(fenshu[k]-'0')*0.1;} //计算浮点数的小数部分fudian=sumint+sumf; //浮点数计算syn=80;p=--c;}else{ch=prog[p];//若是整数,ch等于原来的值 sum=0;while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=prog[++p];}ch=prog[--p];syn=11;}}elseswitch(ch){case'<':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}elseif(ch=='>'){syn=21;token[m++]=ch;}else{syn=20;ch=prog[--p];}break;case'>':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;ch=prog[--p];}break;case'=':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=25;token[m++]=ch;}else{syn=18;ch=prog[--p];}break;case'!':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m++]=ch;}else{syn=-1;p--;}break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break;default:syn=-1;}}七、测试用例:补充:功能扩展测试用例:八、程序输出结果:功能扩展测试用例输出结果用例一:用例二:用例三:普通功能测试用例显示结果九、实验心得通过编译原理实验一词法分析实验,使得自己对词法分析的流程有了更深刻的了解,虽然源代码并非由自己设计,但是在调试程序的过程中,尤其是进行测序功能扩展的过程中,想了很多种办法,终于找到了最合适的方法,而且还进行了代码的优化,这个过程虽然有时有些枯燥,但是更多时候是欣喜的,不仅复习了c语言的许多内容,并且有了更深的理解。