C_minus语言词法分析器实验报告
(完整版)C语言词法分析器实验报告汇总
计算机科学与工程系编译原理课程设计实验报告扫描数字: 是f 判别为自减符Ch 是否为‘-'判别为”-> ”预读ch预读ch判别为负号 回退3Ch 为数字或‘预读ch扫描引号:扫描单词:实验步骤:1、准备:用TC、VC++等开发工具;2、对本实验的任务进行分析,确定实现功能的函数;3、写好程序,仔细修改函数;4、上机操作:输入源程序,修改、调试,运行。
5、写好试验报告。
实验调试过程及测试结果代^码******************************/#in clude<stdio.h> #in clude<stdlib.h> #in elude <ctype.h> #in clude<stri ng.h> void mai n()FILE *fp,*fp1;int guanjz(char ch1[]);〃关键字和标识符判断int hanjsq=1;〃行计数器,保存行号char ch,infile[15],outfile[15];〃定义输入和输出文件名prin tf("*****************E nter the infilename*****************sca nf("%s",i nfile);// 输入需要扫描的文件名printf( Enter the outfile n ame******************\n");scan f("%s",outfile);// 输入需要另存为的文件名if((fp = fope n(i nfile,"r")) == NULL)// {prin tf("ca nnot ope n file\n");exit(0);}if((fp1 = fope n(outfile,"w")) == NULL)// 打开需要扫描的文件打开需要存入的文件/*******************************{printf("cannot open file'n"); exit(O); }printf("\n******************************************************** printf( "******************************************************* printf("\n******************************************************** printf( "******************************************************* fprin tf(fp1,"*******************************************************fprin tf(fp1, while(!feof(fp)) {ch=fgetc(fp); if(ch==1O)hanjsq++;if(isalpha(ch) || ch=='_')〃 如果第一个字符为字母或下划线则判断为标识符{int i=0; char ch1[30];〃 假疋母个标识付取长为ch1[i++]=ch;〃将ch 保存到ch1[0]中并使i 自加1while(!feof(fp)) {ch=fgetc(fp);if(ch==1O)hanjsq++;〃 如果ch 为换行符,则行计数器自加 1if(isalpha(ch) || isdigit(ch) || ch=='')扫描头文件单词及保留字*********************printf("* 》开始进行词法分析 《*\ n");printf (”行号 字符串 种别码\n");fprin tf(fp1,"行号 字符串 种别码\n"); **\ n");{fseek(fp,-1,1);//fp 回退 1ch1[i]='\0';〃 把结束标志放到 ch1[i]中作为单词结束标志prin tf("li ne %d:%s%d\n",hanjsq,ch1,guanjz(ch1));〃以字符串形式输fprin tf(fp1,"li ne %d: %s%d\n" ,hanjsq,ch1,guanjz(ch1));break; }} if(!isalpha(ch) && !isdigit(ch) && ch!='_' && ch!='.') {//如果ch 不为字母、数字、下划线和点时判断其为标识符ch1[i]='\0'; prin tf("li ne %d: fprin tf(fp1,"li ne %d:%s{//如果ch 为字母、数字或下划线就把ch 放到ch1[i]中并使i 自加1ch1[i++]=ch; }if(ch=='.')〃 如果ch 为小数点则判断是否为头文件{if((ch=fgetc(fp))=='h')〃如果小数点后一位为 h 则判定其为头文件{if(ch==10)hanjsq++; chi[i++]='.'; chi[i++]='h'; ch1[i]='\0';〃 把结束标志放到 chi[i]中作为单词结束标志prin tf("li ne %d: %s83\n",hanjsq,ch1);〃以字符串形式输出 ch1fprin tf(fp1,"li ne %d: %s83\n",hanjsq,ch1);break;else//如果小数点后一位不是h 则判定其为标识符出chi%s%d\n",hanjsq,ch1,guanjz(ch1)); %d\n ”,hanjsq,ch1,guanjz(ch1));if(isdigit(ch) || ch=='-')〃如果ch 为数字或'-'if(isdigit(ch))//如果ch 为数字prin tf("li ne %d:%c",hanjsq,ch);while(!feof(fp))if(isdigit(ch) || ch=='.')prin tf("%c",ch); fprin tf(fp1,"%c",ch);else//否则视为数字结束printf (” fprin tf(fp1,"ch='O :〃 置ch 为0,以免影响下面误判并顺利退出扫描数字 break;break;/************************j 扫描数*************************/fprintf(fp1,"line %d: %c",hanjsq,ch);ch=fgetc(fp);〃预读一位如果 ch 为数字和点则循环输出46\n");46\n");fseek(fp,-1,1);〃回退一位if(ch=='-')〃如果ch 为'-'ch=fgetc(fp);〃 预读一位if (ch=='-')〃 如果ch 还是为'-'则判断为自减符'--' {prin tf("li ne %d: fprintf(fp1,"line %d: }if(isdigit(ch))〃 如果ch 为数字则可能为减号或负号{fseek(fp,-3,1);〃 回退 3 为判断ch=fgetc(fp); if(isdigit(ch))〃如果ch 为数字则判断'-'为减号ch=fgetc(fp); prin tf("li ne %d:%cfprin tf(fp1,"li ne %d: }else //否则判断'-'为负号 {ch=fgetc(fp); prin tf("li ne %d: fprin tf(fp1,"li ne %d: while(!feof(fp)) {ch=fgetc(fp);〃79\n" ,hanjsq,ch);%c 79\n",hanjsq,ch);80\n",hanjsq);80\n",hanjsq);如果ch 为'>',则判断为结构体运算符’->'{prin tf("li ne %d:->fprin tf(fp1,"li ne %d:->81\ n",hanjsq);81\ n",hanjsq);预读一位如果 %c",hanjsq,ch);%c",hanjsq,ch);ch 为数字和点则循环输出if(ch=='>')〃 }if(isdigit(ch) || ch=='.') {prin tf("%c",ch);fprin tf(fp1,"%c",ch);}扫描注释**********************else//否则视为数字结束{printf(”46\n");fprin tf(fp1," 46\n");fseek(fp,-1,1);// 回退1break;}}}if(ch=='/')〃如果ch为'/'则可能为注释{ch=fgetc(fp);〃读下一个字符if(ch==10)hanjsq++;if(ch=='/')〃如果该字符也为'/'则判断为注释一行{while(fgetc(fp)!=10);if(ch==10)hanjsq++;〃直到遇到换行符出现才认为注释结束}if(ch=='*')〃如果该字符为'*'则判断为注释多行{//直到出现’*/' 才认为注释结束while(!feof(fp)) {ch=fgetc(fp); if(ch==10)hanjsq++; if(ch=='*')〃 出现'*'{//且接着出现'/' if((ch=fgetc(fp))=='/')break;while(!feof(fp))else// 否则原样输出'/'prin tf("li ne %d: fprintf(fp1,"line %d:83\n",hanjsq);83\n",hanjsq);fseek(fp,-1,1);〃 回退1break;/***********************扫描引号 ************************/ if(ch==””)〃出现引号int i=0;prin tf("li ne %d:%cfprin tf(fp1,"li ne %d: %c 82\n",hanjsq,ch);82\n",hanjsq,ch);prin tf("li ne %d: ",hanjsq);fprin tf(fp1,"li ne %d:",hanjsq);{//先整体输出引号内所有字符并定为第99类ch=fgetc(fp);i++;〃用于积累回退长度 if(ch==10)hanjsq++; if(ch!=””) {if(ch!=32) {prin tf("%c",ch); fprin tf(fp1,"%c",ch); } }else break;} printf (” fprin tf(fp1," fseek(fp,-i,1);// for(;i>0;i--) {ch=fgetc(fp);if(ch==92)// 如果ch 为'\'则可能为转义字符 {char ch5[13]={"abfntv\\?'\"0"}; // 转义字符集ch=fgetc(fp);// 预读一位 for(int k=0;k<12;k++) {//如果为转义字符则输出if(ch==ch5[k]) {99\n");99\n");回退到引号开始printf(”line %d: \\%c%d\n" ,hanjsq,ch,k+33);fprin tf(fp1," li ne %d: \\%c }}if(ch=='d' && isdigit(fgetc(fp)) && isdigit(fgetc(fp)))〃{fseek(fp,-2,1);prin tf(" line %d: %c%cfprin tf(fp1," line %d: %c%c }if(ch=='x' && isdigit(fgetc(fp)) && isdigit(fgetc(fp)))//{fseek(fp,-2,1);prin tf(" line %d: %c%cfprin tf(fp1," line %d: %c%c }}if(ch=='%')〃如果为'%'则可能为%s%c%d%d\n",hanjsq,ch,k+33);任意字符转换为三位八进制44\n",hanjsq,fgetc(fp),fgetc(fp));44\n “,hanjsq,fgetc(fp),fgetc(fp));任意字符转换为二位十六进制45\n",hanjsq,fgetc(fp),fgetc(fp));45\n",hanjsq,fgetc(fp),fgetc(fp));{ch=fgetc(fp);char bfh[4]={"dcs"};for(i=0;i<3;i++){if(bfh[i]==ch){prin tf(" line %d: %%%c fprin tf(fp1," line %d: %%%c 83\n",hanjsq,ch);83\n",hanjsq,ch);}}}}描其他符^号 ********************/if(!isdigit(ch) && !isalpha(ch) && ch!='_' && ch!=”” && ch!='/')char ch2[14]={"#()[]{}'*:~%A"};〃for(i nt i=0;i<13;i++) {//判断单个符号if(ch==ch2[i])for(i nt j=0;j<8;j++) {//判断双符号if(ch==ch3[j])ch=fgetc(fp);//预读一位//if(ch==10)hanjsq++; if(ch==ch4[j]){//且ch 与ch4第j 个匹配,则表示 ch3[j]与ch4[j]if(ch=='<' && ch3[j]=='<')〃prin tf("li ne %d:%c%c%d\n",hanjsq,ch3[j],ch4[j],i+69);fprin tf(fp1,"li ne %d:%c%c%d\n",hanjsq,ch3[j],ch4[j],i+69);/*********************char ch3[9]={"+?=|&!<>"};// 定义部分单符号或双符号(前半部分)集 char ch4[9]={"+==|&==="};//定义部分双符号(后半部分)定义部分单符号集prin tf("li ne %d: %c%d\n" ,hanjsq,ch,i+48);fprintf(fp1,"line %d:%c%d\n",hanjsq,ch,i+48);{//如果ch 与ch3中第j个字符匹配 连起来为一个双符号判断'<<'符prin tf("li ne %d:fprin tf(fp1,"li ne %d:}if(ch=='>' &&ch3[j]=='>')〃{prin tf("li ne %d:fprin tf(fp1,"li ne %d:}else//否则表示ch3[j]{prin tf("li ne %d:fprin tf(fp1,"li ne %d:fseek(fp,-1,1);}}}}<<<<判断'>>'符>>>>为单符号,不是双符号的%c%c77\n",hanjsq);77\n",hanjsq);78\n",hanjsq);78\n",hanjsq);部分%d\n",hanjsq,ch3[j],j+61);%d\n" ,hanjsq,ch3[j],j+61)****************************************************************************************** printf( **\n");prin tf("* 》词法分析结束prin tf("* 》分析结果保存在文件%$中prin tf("* 》欢迎下次使用,谢谢!《*\n"); 《*\ n",outfile);《*\n");printf( **\n");fprin tf(fp1, **\ n");fprin tf(fp1,"*》词法分析结束《*\n");fprin tf(fp1,"*》欢迎下次使用,谢谢! 《*\n");-21-**\ n");in t guanjz(char ch1[])〃 关键字和标识符判断{char ch2[32][9]={"auto","double","i nt","struct","break","else","lo ng","switch","case","e num","register","typedef","char","extern","return","u nio n","co nst","float","short", "un sig ned","co nti nue","for","sig ned","void","default","goto","sizeof', "volatile","do","while","static","if"};〃for(int i=0;i<32;i++){//逐个比对如果为关键字则返回类别i+1if(!strcmp(ch1,ch2[i]))return i+1;return 47;//否则返回一般标识符类竝船悅Q )動勒卜1 Inc 1: u 4Sline 12 iniclude 4?1 ine 1* <b'fline 1 =. Ili B3lino is >hVlliw 2s U 4Rlima 2s inaludo 47a I M 2? <67 line 2s atAlib.hlinfi 2: > GS line 3; voidline main<17 line 3: <J. inc 3 = > ba line 3: S3 1 inc Ss riLE47 1 Irte 5:lime S ; __ s4?test・曹■:M 曹Entei' t hs outf ile ri 之盯日****^***-¥******<^^ cf F MQI , txt a t ■ w a w at it at ■ at ituif at it at U tguit at ■ • ac n unit ar ・ a t ariMiM at MTM a t :M at ■ u at 心 开史舱行词法分析 <* 讪:"Ik 1: 血1: line 1: Ike]: H UE 2: Iine2: line 2: lines : !k2: line 3: line 3: line 5; line 3: lineS: lint 5: J5QE 5:inclu tstdin hCaiLFIL E丰ft:■:•S3=;阴i 7占fl定义关键字集-22 -:B 豪溥■ ar 河*"百■苜筒n w i {耳鼻p n t 尸广 『卄戸1 nt- _i I n Finp 卄 可・w 耳黑図耳溥■ ar ・鼻*E E 戸F trst«t 具t■ if 耳材imcirHirjtKjnf i fK^nrBl* Th& outf lie 寺暮打補整并*需斗弭書!**祥略再整番 cffXQ-tXt at ir uif at ■ u u KM at ■・ at MENU at ■ U M ~W ;M a t WM a t aa ・:■■■!< IT ar ~K af M E :I m a t at nwu at心开给进行词法分析 3 =!K X KM X MM X X MJ4 K M M X KM X K M X MMX M M M MM M X K M X <M MM MM MMX KKXXMM X MM K MMK K liine line 丄±n& line lino 1 irie linn llnft line liri@ Urie line line 丄inc line linn line line n include stdllo .li includostdlib.lh uo id Piaui PILE 48 4? G7 83 bS 1? 67 68 24 4?印呼 bU 53 4? -1? Line 2C 4Gi Limo 2^鼻llna 26 cnimt 47Line 2& >Line 27 9 JlE & E Line 27 if3Z line 27 C 49 Lime H7 st>£rii^ 47 line 2? C 51 Line 2? 1 47 Line 27 J ^2 Lime 2? 71 Lino 2? ■ «3Jifle 7.7=Livw 2? i 55 Lino 2? > saline 27 55Line 27 > 50 Lino 28 printf 47 1 Ine 2» C 49 Line 20 ii S2Lino 纫 xd\n1血2& + 61 lint 2& T alint 2&■ccmtrlint 26 1 ) 50 line A else6血27 if $IT f X49 1血H Etring Ji 血H [ 51]ine 牙 1 1 rlillE H ] 血H LIM 二line 卵 -1遊H1遊2T)血2TJ 1]inc 2T )line 28 printf 眄 line 28 ■:191U23 ifI LDE 28册-23 -liit 31: liiE 31:y Ike y c-uritrirqiue printFine 3U:<V Igf PF FInCKdXnNdine SI R *\n+ +++c a unt分析结果保总结:lhe加line 29: 1血亚line 3:lii诃;line SO;lbue 50:\be30:line 30:line:fl:Hie 50:luie 馬:血数lhs33!line J3:):rintf(*rfrrfinlMtnHJ\p卄i:wqJIq:4r»-I—ru=rfc-pFlL.■i^u-In—r^vFhdfLJ.rkj"rnuriui指导教师签名:2011年4月12日星期二。
C-Minus词法分析和语法分析设计编译器编译原理课程设计
编译原理课程设计报告课题名称:C- Minus词法分析和语法分析设计1.课程设计目标实验建立C-编译器。
只含有扫描程序(scanner)和语法分析(parser)部分。
2.分析与设计C-编译器设计的整体框架,本实验实现扫描处理和语法分析程序(图中粗黑部分)。
打开源代码文件source.txt扫描处理(词法分析)记号语法分析程序语法树语义分析程序错误处理器注释树记号表源代码优化程序文字表中间代码代码生成器目标代码目标代码优化程序目标代码2.1 、扫描程序scanner部分2.1.1系统设计思想设计思想:根据DFA图用switch-case结构实现状态转换。
惯用词法:① 语言的关键字:else if int return void while② 专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */③ 其他标记是ID和NUM,通过下列正则表达式定义:ID = letter letter* NUM = digit digit*letter = a|..|z|A|..|Z digit = 0|..|9大写和小写字母是有区别的④ 空格由空白、换行符和制表符组成。
空格通常被忽略,除了它必须分开ID、NUM关键字。
⑤ 注释用通常的C语言符号/ * . . . * /围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。
注释不能嵌套scanner的DFA/+ - * <= >= == != ; , ( ) [] { }INASSIGNWhite space >,<,=,!=digit\t \n[other]NUMdigit[other]STARTDONEletter[other]letterINID[other]ZHU*/[other]INCOMMENT*[other]ZZHU*说明:当输入的字符使DFA到达接受状态的时候,则可以确定一个单词了。
词法分析器实验报告
词法分析器实验报告引言:词法分析器(Lexical Analyzer)是编译器的重要组成部分,其主要任务是将源代码转化为一个个独立的词法单元,为语法分析器提供输入。
在本次实验中,我们设计并实现了一个简单的词法分析器,通过对其功能和性能的测试,评估其在不同场景下的表现。
实验目的:1. 确定词法分析器的输入和输出要求;2. 通过构建适当的正则表达式规则,匹配不同类型的词法单元;3. 实现一个高效的词法分析器,确保在处理大型源代码时性能不受影响;4. 对词法分析器的功能和性能进行测试和评估。
实验过程:1. 设计词法分析器的接口:1.1 确定输入:源代码字符串。
1.2 确定输出:词法单元流,每个词法单元包含类型和对应的字符串值。
2. 构建正则表达式规则:2.1 识别关键字:根据编程语言的关键字列表构建正则表达式规则,将关键字与标识符区分开。
2.2 识别标识符:一般由字母、下划线和数字组成,且以字母或下划线开头。
2.3 识别数字:整数和浮点数可以使用不同的规则来识别。
2.4 识别字符串:使用引号(单引号或双引号)包裹的字符序列。
2.5 识别特殊符号:各类操作符、括号、分号等特殊符号需要单独进行规则设计。
3. 实现词法分析器:3.1 读取源代码字符串:逐个字符读取源代码字符串,并根据正则表达式规则进行匹配。
3.2 保存词法单元:将匹配到的词法单元保存到一个词法单元流中。
3.3 返回词法单元流:将词法单元流返回给调用者。
4. 功能测试:4.1 编写测试用例:针对不同类型的词法单元编写测试用例,包括关键字、标识符、数字、字符串和特殊符号。
4.2 执行测试用例:将测试用例作为输入传递给词法分析器,并检查输出是否和预期一致。
4.3 处理错误情况:测试词法分析器对于错误输入的处理情况,如非法字符等。
5. 性能测试:5.1 构建大型源代码文件:生成包含大量代码行数的源代码文件。
5.2 执行词法分析:使用大型源代码文件作为输入,测试词法分析器的性能。
C-Minus词法分析报告四川大学编译原理
内层CASE判断getNextChar()获取的下一个字符使当前状态转换为其他状态。
关键代码分析
TokenType getToken(void)
} TokenType;
//定义状态类型
typedef enum { START,LBUFFER,RBUFFER,INCOMMENT,INNUM,INID,INEQ,INLE,INGE,INNEQ,DONE }StateType;
//结构定义
static struct
{ char *str;
TokenType tok;
}
实验结果截图
总结
词法分析程序的输出和输入:词法分析程序的功能是读入源程序,输出单词符号。单词符号是程序设计语言的本语法符号,程序设计语言的单词符号一般分为如下几种:关键字,标示符,常数,运算符,界符,单词的输出是二元式的形式,需要知道二元式的表示方法,把得到的二元式写入输出文件。
实验注意事项:
1.试验中在设计注释部分的解析时,因为C-Minus的注释符是四个字符组成,设计DFA时设计了两个中间态,用来判断状态转换;在代码中,如果由中间态转换为INCOMMENT状态,注意字符回退和save置false
currentToken=ENDFILE;
}
else
state=INCOMMENT;
break;
}
case INNUM:{
if(!isdigit(c))
{
ungetNextChar();
save=FALSE;
词法分析器实验报告
词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对C语言代码进行词法分析的程序。
该程序能够将源代码分解成关键字、标识符、常量、运算符等各种词法单元,并输出其对应的词法类别。
三、实验方法1. 设计词法规则:根据C语言的词法规则,设计相应的正则表达式来描述各种词法单元的模式。
2. 实现词法分析器:利用编程语言(如Python)实现词法分析器,将源代码作为输入,根据词法规则将其分解成各种词法单元,并输出其类别。
3. 测试和调试:编写测试用例,对词法分析器进行测试和调试,确保其能够正确地识别和输出各种词法单元。
四、实验过程1. 设计词法规则:根据C语言的词法规则,我们需要设计正则表达式来描述各种词法单元的模式。
例如,关键字可以使用'|'操作符将所有关键字列举出来,标识符可以使用[a-zA-Z_][a-zA-Z0-9_]*的模式来匹配,常量可以使用[0-9]+的模式来匹配等等。
2. 实现词法分析器:我们选择使用Python来实现词法分析器。
首先,我们需要读取源代码文件,并将其按行分解。
然后,针对每一行的代码,我们使用正则表达式进行匹配,以识别各种词法单元。
最后,我们将识别出的词法单元输出到一个结果文件中。
3. 测试和调试:我们编写了一系列的测试用例,包括各种不同的C语言代码片段,以测试词法分析器的正确性和鲁棒性。
通过逐个测试用例的运行结果,我们可以发现和解决词法分析器中的问题,并进行相应的调试。
五、实验结果经过多次测试和调试,我们的词法分析器能够正确地将C语言代码分解成各种词法单元,并输出其对应的类别。
例如,对于输入的代码片段:```cint main() {int a = 10;printf("Hello, world!\n");return 0;}```我们的词法分析器将输出以下结果:```关键字:int标识符:main运算符:(运算符:)运算符:{关键字:int标识符:a运算符:=常量:10运算符:;标识符:printf运算符:(常量:"Hello, world!\n"运算符:)运算符:;关键字:return常量:0运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
[汇编]C_minus语言词法分析器的设计
实验一:词法分析程序的设计与实现姓名:专业班级:学号:一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的理解。
二.、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求根据PL/0语言文法,编制词法分析程序GETSYM完成以下功能:1)从键盘读入数据,分析出一个单词。
2)返回单词种别(用整数表示),3)返回单词属性(不同的属性可以放在不同的全局变量中)。
四.、实验步骤1. 采用C语言,设计GETSYM ,实现该算法2. 编制测试程序(主函数main)。
3. 调试程序:输入一组单词,检查输出结果。
五.、实验设计分析1.词法的正规式描述S=aA|aA=(aA|dA)}(a|d)2.变换后的正规文法S→aAS→aA→aAA→dAA→aA→d3.词法分析程序的程序代码#include "stdafx.h"#include <iostream>#include<string>using namespace std;#define MAX 17char ch =' ';stringkey[17]={"const","long","float","double","void","main","if","else","then","break","int","char","in clude","for","while","printf","scanf"};int Iskey(string c){ //关键字判断int i;for(i=0;i<MAX;i++){if(key[i].compare(c)==0) return 1;}return 0;}int IsLetter(char c){ //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsLetter1(char c){ //判断是否为a~f字母if(((c<='f')&&(c>='a'))||((c<='F')&&(c>='A'))) return 1;else return 0;}int IsDigit(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}void scan(FILE *fpin){string arr="";while((ch=fgetc(fpin))!=EOF){arr="";if(ch==' '||ch=='\t'||ch=='\n'){}else if(IsLetter(ch)||ch=='_'){arr=arr+ch;ch=fgetc(fpin);while(IsLetter(ch)||IsDigit(ch)){if((ch<='Z')&&(ch>='A')) ch=ch+32;arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);if (Iskey(arr)){cout<<arr<<"\t关键字"<<endl;}else cout<<arr<<"\t普通标识符"<<endl;}else if(IsDigit(ch)){int flag=0;if(ch=='0'){arr=arr+ch;ch=fgetc(fpin);if(ch>='0'&&ch<='7'){while(ch>='0'&&ch<='7'){flag=1;arr=arr+ch;ch=fgetc(fpin);}}else if(ch=='x'||ch=='X'){flag=2;arr=arr+ch;ch=fgetc(fpin);while(IsDigit(ch)||IsLetter1(ch)){arr=arr+ch;ch=fgetc(fpin);}}else if(ch==' '||ch==','||ch==';' ){cout<<arr<<"\t整数0"<<endl;}fseek(fpin,-1L,SEEK_CUR);if(flag==1) cout<<arr<<"\t八进制整数"<<endl;else if(flag==2) cout<<arr<<"\t十六进制整数"<<endl;}else{arr=arr+ch;ch=fgetc(fpin);while(IsDigit(ch)){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);cout<<arr<<"\t十进制整数"<<endl;}}else switch(ch){case'+':case'-' :case'*' :case'=' :case'|' :case'/' :cout<<ch<<"\t运算符"<<endl;break;case'(' :case')' :case'[' :case']' :case';' :case'.' :case',' :case'{' :case'}' :cout<<ch<<"\t界符"<<endl;break;case':' :{ch=fgetc(fpin);if(ch=='=') cout<<":="<<"\t运算符"<<endl;else{cout<<"::"<<"\t界符"<<endl;;fseek(fpin,-1L,SEEK_CUR);}}break;case'>' :{ch=fgetc(fpin);if(ch=='=') cout<<">="<<"\t运算符"<<endl;if(ch=='>')cout<<">>"<<"\t输入控制符"<<endl;else {cout<<">"<<"\t运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;case'<' :{ch=fgetc(fpin);if(ch=='=')cout<<"<="<<"\t运算符"<<endl;else if(ch=='<')cout<<"<<"<<"\t输出控制符"<<endl;else if(ch=='>') cout<<"<>"<<"\t运算符"<<endl;else{cout<<"<"<<"\t运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;default : cout<<ch<<"\t无法识别字符"<<endl;}}}void main(){char in_fn[30];FILE * fpin;cout<<"请输入源文件名(包括路径和后缀名):";for(;;){cin>>in_fn;if((fpin=fopen(in_fn,"r"))!=NULL) break;else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";}cout<<"\n分析如下:\n"<<endl;scan(fpin);fclose(fpin);}七.实验测试:输入数据及运行结果:int a=3;double b=4;int c;if(a>b)c=a;elsec=b;。
C_minus语言词法分析器的设计
实验一:词法分析程序的设计与实现姓名:专业班级:学号:一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的理解。
二.、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求根据PL/0语言文法,编制词法分析程序GETSYM完成以下功能:1)从键盘读入数据,分析出一个单词。
2)返回单词种别(用整数表示),3)返回单词属性(不同的属性可以放在不同的全局变量中)。
四.、实验步骤1. 采用C语言,设计GETSYM ,实现该算法2. 编制测试程序(主函数main)。
3. 调试程序:输入一组单词,检查输出结果。
五.、实验设计分析1.词法的正规式描述S=aA|aA=(aA|dA)}(a|d)2.变换后的正规文法S→aAS→aA→aAA→dAA→aA→d3.词法分析程序的程序代码#include "stdafx.h"#include <iostream>#include<string>using namespace std;#define MAX 17char ch =' ';stringkey[17]={"const","long","float","double","void","main","if","else","then","break","int","char","in clude","for","while","printf","scanf"};int Iskey(string c){ //关键字判断int i;for(i=0;i<MAX;i++){if(key[i].compare(c)==0) return 1;}return 0;}int IsLetter(char c){ //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;else return 0;}int IsLetter1(char c){ //判断是否为a~f字母if(((c<='f')&&(c>='a'))||((c<='F')&&(c>='A'))) return 1;else return 0;}int IsDigit(char c){ //判断是否为数字if(c>='0'&&c<='9') return 1;else return 0;}void scan(FILE *fpin){string arr="";while((ch=fgetc(fpin))!=EOF){arr="";if(ch==' '||ch=='\t'||ch=='\n'){}else if(IsLetter(ch)||ch=='_'){arr=arr+ch;ch=fgetc(fpin);while(IsLetter(ch)||IsDigit(ch)){if((ch<='Z')&&(ch>='A')) ch=ch+32;arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);if (Iskey(arr)){cout<<arr<<"\t关键字"<<endl;}else cout<<arr<<"\t普通标识符"<<endl;}else if(IsDigit(ch)){int flag=0;if(ch=='0'){arr=arr+ch;ch=fgetc(fpin);if(ch>='0'&&ch<='7'){while(ch>='0'&&ch<='7'){flag=1;arr=arr+ch;ch=fgetc(fpin);}}else if(ch=='x'||ch=='X'){flag=2;arr=arr+ch;ch=fgetc(fpin);while(IsDigit(ch)||IsLetter1(ch)){arr=arr+ch;ch=fgetc(fpin);}}else if(ch==' '||ch==','||ch==';' ){cout<<arr<<"\t整数0"<<endl;}fseek(fpin,-1L,SEEK_CUR);if(flag==1) cout<<arr<<"\t八进制整数"<<endl;else if(flag==2) cout<<arr<<"\t十六进制整数"<<endl;}else{arr=arr+ch;ch=fgetc(fpin);while(IsDigit(ch)){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);cout<<arr<<"\t十进制整数"<<endl;}}else switch(ch){case'+':case'-' :case'*' :case'=' :case'|' :case'/' :cout<<ch<<"\t运算符"<<endl;break;case'(' :case')' :case'[' :case']' :case';' :case'.' :case',' :case'{' :case'}' :cout<<ch<<"\t界符"<<endl;break;case':' :{ch=fgetc(fpin);if(ch=='=') cout<<":="<<"\t运算符"<<endl;else{cout<<"::"<<"\t界符"<<endl;;fseek(fpin,-1L,SEEK_CUR);}}break;case'>' :{ch=fgetc(fpin);if(ch=='=') cout<<">="<<"\t运算符"<<endl;if(ch=='>')cout<<">>"<<"\t输入控制符"<<endl;else {cout<<">"<<"\t运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;case'<' :{ch=fgetc(fpin);if(ch=='=')cout<<"<="<<"\t运算符"<<endl;else if(ch=='<')cout<<"<<"<<"\t输出控制符"<<endl;else if(ch=='>') cout<<"<>"<<"\t运算符"<<endl;else{cout<<"<"<<"\t运算符"<<endl;fseek(fpin,-1L,SEEK_CUR);}}break;default : cout<<ch<<"\t无法识别字符"<<endl;}}}void main(){char in_fn[30];FILE * fpin;cout<<"请输入源文件名(包括路径和后缀名):";for(;;){cin>>in_fn;if((fpin=fopen(in_fn,"r"))!=NULL) break;else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";}cout<<"\n分析如下:\n"<<endl;scan(fpin);fclose(fpin);}七.实验测试:输入数据及运行结果:int a=3;double b=4;int c;if(a>b)c=a;elsec=b;。
词法分析器实验报告
实验一词法分析一、实验目的:通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
(遇到错误时可显示“Error”,然后跳过错误部分继续显示)二、实验过程和指导:(一)准备:1.阅读课本有关章节,明确语言的语法,写出基本保留字、标识符、常数、运算符、分隔符和程序例。
2.初步编制好程序。
3.准备好多组测试数据。
(二)上课上机:将源代码拷贝到机上调试,发现错误,再修改完善。
第二次上机调试通过。
(三)程序要求:程序输入/输出示例:Array如源程序为C语言。
输入如下一段:main(){int a,b;a = 10;b = a + 20;}#要求输出如右图。
:1、将单词分为五种识别关键字:main、if、int、for、while、do、return、break、continue;单词种别码为1。
标识符;单词种别码为2。
常数为无符号整形数;单词种别码为3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符包括:,、;、{、}、(、);单词种别码为5。
三、部分代码:#include "stdafx.h"#include<string.h>#include<stdio.h>#include<stdlib.h>#include<ctype.h>char *table[7]={" ","main","int","if","while","else","return"},TOKEN[20],ch; //定义关键字/*int lookup(char *TOKEN){ //关键字匹配函数if((m=strcmp(TOKEN,table[i]))==0)}*/void out(int c,char *TOKEN){ //输出函数printf("(%d,%s)\n",c,TOKEN);}bool zimu(char ch){if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){return true;}else{return false;}}bool shuzi(char ch){if(ch>='0'&&ch<='9'){return true;}else{return false;}}void scanner(FILE *fp){ //扫描函数char TOKEN[20]={'\0'};char ch;int i,c;ch=fgetc(fp); //获取字符,指针fp并自动指向下一个字符if(zimu(ch)){ //判断该字符是否是字母TOKEN[0]=ch;ch=fgetc(fp);i=1;while(shuzi(ch)|| zimu(ch)){ //判断该字符是否是字母或数字TOKEN[i]=ch;i++;ch=fgetc(fp);}fseek(fp,-1,1);out(2,TOKEN);}else if(shuzi(ch)){TOKEN[0]=ch;ch=fgetc(fp);fseek(fp,-1,1);out(3,TOKEN);}else if(ch=='+') out(4,"+");else if(ch=='-') out(4,"-");else if(ch=='*') out(4,"*");else if(ch=='/') out(4,"/");else if(ch=='(') out(4,"(");else if(ch==')') out(4,")");}main(){FILE *fp;if((fp=fopen("E:\\222.txt","r"))==NULL){ //读取文件内容,并返回文件指针,该指针指向文件的第一个字符fprintf(stderr,"error opening.\n");exit(1);}do{ch=fgetc(fp);if(ch=='#') //文件以#结尾,作为扫描结束条件break;if(ch==' ') //如果是空格,自动跳到下个字符scanner(fp);else{fseek(fp,-1,1); //如果不是空格,则回退一个字符并扫描scanner(fp);}}while(ch!='#');return(0);}四、测试结果:五、总结:词法分析的实验已经结束,在这为期两个课时的时间里,我学习到了很多,利用此次实验又重新学习了一遍C语言的有关内容,也进一步了解和掌握了词法分析器的概念和原理。
C_minus语言词法分析器实验报告
编译原理实验报告
题目 : C_minus 语言词法分析器
装 订 线
学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx 学 号 xxxxxxxxxxxx 姓 名 xxxx 指导教师 xxxx
20xx 年 xx 月 xx 日
.
.
C_minus 语言词法分析器
一、实验目的
1. 理解词法分析器的设计方法:利用 DFA编写相应的程序。 2. 掌握手工编写词法分析程序的方法。 3. 复习熟悉以前学过的编程语言 4. 通过实验了解编译器词法分析的工作原理
四、实验结果(程序)及分析
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 100
typedef struct {
char name[30];
int code;
int addr;
}token;// 存储刚从文件中读取的字符
typedef struct {
h=0; } else{
h=1; break; } } if(h==0) break; } if(h==0) { current.code=key[i].code; output_1(); } else{ strcpy(symboltable[addr_count].name,); symboltable[addr_count].code=10; symboltable[addr_count].addr=addr_count;
isnumber(); else isOthers(); ch=fgetc(source); } fclose(source); fclose(keytxt); fclose(badgetxt); fclose(othertxt); fclose(number); } void iskeyword(){ int i=0,k=0,j=0; int h=0; while(((ch>='a') && (ch<='z')) ||((ch>='A') && (ch<='Z')) || ch=='_' || (ch> '0' && ch<'9')) { [i]=ch; i++; ch=fgetc(source); } zancun=current; for(i=0;i<6;i++) { for(j=0;j<30;j++) { if([j]==key[i].name[j]){
C-Minus词法分析四川大学编译原理
四川大学计算机学院、软件学院实验报告学号姓名:专业:DFA数据类型数据结构设计//定义数据类型TokenTypetypedef enum{ENDFILE,ERROR,IF,ELSE,INT,RETURN,VOID,WHILE,ID,NUM,ASSIGN,EQ,LT,LE,GT,GE,NEQ,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,LBRACKET,RBRACKET,LBRACE,RBRACE,COMMA,SEMI} TokenType;//定义状态类型typedef enum{ START,LBUFFER,RBUFFER,INCOMMENT,INNUM,INID,INEQ,INLE,INGE,INNEQ,DO NE }StateType;//结构定义实验结果截图总结词法分析程序的输出和输入:词法分析程序的功能是读入源程序,输出单词符号。
单词符号是程序设计语言的本语法符号,程序设计语言的单词符号一般分为如下几种:关键字,标示符,常数,运算符,界符,单词的输出是二元式的形式,需要知道二元式的表示方法,把得到的二元式写入输出文件。
实验注意事项:1.试验中在设计注释部分的解析时,因为C-Minus的注释符是四个字符组成,设计DFA时设计了两个中间态,用来判断状态转换;在代码中,如果由中间态转换为INCOMMENT状态,注意字符回退和save置false2.在判断运算符<,<=,>,>=,!=时,第二字符是’=’可成功识别出运算符,第二字符是其他字符时也可能是合法符号,注意字符回退与token判断。
参考资料:《编译原理及实践/编译器设计方案》。
词法分析器实验报告
词法分析器实验报告词法分析器设计一、实验目的:对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
利用该词法分析器完成对源程序字符串的词法分析。
输出形式是源程序的单词符号二元式的代码,并保存到文件中。
二、实验内容:1. 设计原理词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。
理论基础:有限自动机、正规文法、正规式词法分析器(Lexical Analyzer) 又称扫描器(Scanner):执行词法分析的程序2. 词法分析器的功能和输出形式功能:输入源程序、输出单词符号程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符,界符3. 输出的单词符号的表示形式:单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。
4. 词法分析器的结构单词符号5. 状态转换图实现三、程序设计1.总体模块设计/*用来存储目标文件名*/string ;/*提取文本文件中的信息。
*/string GetText();/*获得一个单词符号,从位置i开始查找。
并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。
*/string GetWord(string str,int i,int& j);/*这个函数用来除去字符串中连续的空格和换行int DeleteNull(string str,int i);/*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/bool IsBoundary(string str,int i);/*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/bool IsOperation(string str,int i);/*此函数将一个pair数组输出到一个文件中*/void Out<pair<int,string> > v);/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/vector<pair<int,string> > analyst(vector<string> vec);/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/ bool IsKey(string str);2.各模块设计(1).首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图;(2).定义相关的变量和数据结构。
Cminus语言词法分析器的设计
实验一:词法分析程序的设计与实现姓名:专业班级:学号:一、实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的理解。
二.、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求根据P L/0语言文法,编制词法分析程序GETS YM完成以下功能:1)从键盘读入数据,分析出一个单词。
2)返回单词种别(用整数表示),3)返回单词属性(不同的属性可以放在不同的全局变量中)。
四.、实验步骤1. 采用C语言,设计GETSYM,实现该算法2.编制测试程序(主函数main)。
3.调试程序:输入一组单词,检查输出结果。
五.、实验设计分析1.词法的正规式描述S=a A|aA=(aA|dA)}(a|d)2.变换后的正规文法S→aAS→aA→aAA→dAA→aA→d3.词法分析程序的程序代码#incl ude"stda fx.h"#in clude<io stream>#include<s tring>us ing namesp ace std;#define MA X 17 c harch =' ';s trin gkey[17]={"cons t","long","float","d ouble","vo id","main","if","e ls e","the n","break","i nt","char","in clude","f or","wh il e","print f","scanf"};int I skey(strin g c){ //关键字判断inti;for(i=0;i<MAX;i++){if(key[i].compa re(c)==0)return 1;}return 0;}int IsL etter(char c){ //判断是否为字母if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) re tur n 1;e lse r eturn 0;}intIsL etter1(ch ar c){//判断是否为a~f字母if(((c<='f')&&(c>='a'))||((c<='F')&&(c>='A'))) re turn 1;elser eturn 0;}int IsD igit(charc){ //判断是否为数字i f(c>='0'&&c<='9') re turn 1;else re tu rn 0;}v oid scan(FILE *fpin){st ring arr="";whi le((ch=fge tc(fp in))!=EOF){ar r=""; if(ch==' '||ch=='\t'||ch=='\n'){}else if(I sLet ter(ch)||ch=='_'){a rr=arr+ch;ch=fg etc(fpin);wh ile(Is Lett er(ch)||Is Digi t(ch)){if((ch<='Z')&&(ch>='A')) ch=ch+32; a rr=ar r+ch;c h=fgetc(f pin);}fseek(fp in,-1L,SE EK_CUR);if(Is key(arr)){cout<<ar r<<"\t关键字"<<endl;}elseco ut<<ar r<<"\t普通标识符"<<endl;}elseif(IsDigit(ch)){int fl ag=0;if(ch=='0'){arr=arr+ch;ch=f getc(f pin);i f(ch>='0'&&ch<='7'){wh ile(ch>='0'&&ch<='7'){f lag=1;arr=ar r+ch;ch=fgetc(fpin);}}else if(ch=='x'||ch=='X'){f lag=2;arr=a rr+ch;ch=fgetc(fpin);w hile(Is Dig it(ch)||Is Lette r1(ch)){arr=arr+c h;ch=fget c(fpin);}}els e if(ch==' '||ch==','||ch==';'){cout<<arr<<"\t整数0"<<en dl;}fs eek(fpin,-1L,S EEK_CUR);i f(flag==1) cout<<a rr<<"\t八进制整数"<<end l;e lse if(fl ag==2) cout<<arr<<"\t十六进制整数"<<en dl;}else{arr=ar r+ch;ch=fg etc(fpin);wh ile(Is Dig it(ch)){arr=arr+ch;ch=fget c(fpi n);}fs eek(fpin,-1L,SEEK_C UR);cout<<a rr<<"\t十进制整数"<<endl;}}el se switch(ch){ca se'+':case'-' :case'*' :case'=' :case'|' :case'/' :cout<<ch<<"\t运算符"<<e ndl;break;case'(' :case')':case'[' :ca se']' :case';':c ase'.' :cas e',' :case'{' :case'}':cout<<ch<<"\t界符"<<en dl;bre ak;case':':{ch=fg et c(fpin);if(ch=='=') c ou t<<":="<<"\t运算符"<<en dl;el se{cout<<"::"<<"\t界符"<<endl;;fseek(fpi n,-1L,SEE K_CUR);}}break;c ase'>' :{ch=f getc(fpin);if(c h=='=') c out<<">="<<"\t运算符"<<endl;if(c h=='>')co ut<<">>"<<"\t输入控制符"<<endl;else {cout<<">"<<"\t运算符"<<endl;fse ek(fpin,-1L,SEEK_CUR);}}break;case'<' :{ch=fgetc(fpi n);if(ch=='=')cout<<"<="<<"\t运算符"<<end l;elseif(ch=='<')c out<<"<<"<<"\t输出控制符"<<endl;el seif(ch=='>') cou t<<"<>"<<"\t运算符"<<endl;else{c out<<"<"<<"\t运算符"<<e ndl;f seek(f pin,-1L,SE EK_CUR);}}break;d efa ult :cout<<ch<<"\t无法识别字符"<<en dl;}}}voidmain(){char in_fn[30];FILE *f pin;co ut<<"请输入源文件名(包括路径和后缀名):";f or(;;){cin>>i n_fn;if((fp in=fopen(i n_fn,"r"))!=NULL) br eak;els e cou t<<"文件路径错误!请输入源文件名(包括路径和后缀名):";}cout<<"\n分析如下:\n"<<endl;scan(fp in);f clos e(fpi n);}七.实验测试:输入数据及运行结果:i nt a=3;d ouble b=4;int c;i f(a>b)c=a;elsec=b;。
词法分析_Cminus
C-MINUS语言是C语言的一个子集,不支持C语言的指针等复杂操作。
但支持函数调用,支持递归调用。
●关键字else if int return void while六个。
所有的关键字都是保留字,并且必须是小写。
●C-MINUS语言专用符号+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */●C-语言其他标记ID和NUM,通过下列正则表达式定义:ID = letter (letter*|digit*)letter*NUM = digit digit*letter = a|..|z|A|..|Zdigit = 0|..|9小写和大写字母是有区别的。
●空格空格通常被忽略,除了它必须分开ID、NUM关键字。
●注释用通常的C语言符号/ * . . . * /围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。
注释不能嵌套。
如下面的C-MINUS源程序片段(C-MINUS程序一般用.cm为后缀):求解最大公因子的程序:(gcd.cm)/* A program to perform Euclid's*Algorithm to compute gcd. */int gcd (int u, int v){if (v == 0) return u ;else return gcd(v,u-u/v*v);/* u-u/v*v == u mod v */}void main(void){int x; int y;x = input();y = input();output ( gcd ( x , y ) ) ;}。
C_minus语言词法分析器的设计
计算机学院编译原理实验报告年级2008级学号姓名成绩专业实验地点指导教师实验项目C_minus语言词法分析器的设计实验日期实验报告要求:一、实验目的设计编写并调试一个词法分析程序,能够完成读入源程序,输出单词符号的功能。
加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编写一个读单词的过程,从输入的源程序中识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符和界符五大类单词,并依次输出各个单词的内部编码及单词符号自身的值。
二、实验原理词法分析是编译的第一个阶段,他的主要任务是从左至右逐个字符地对源程序进行扫描,产生一个个单词序列用以语法分析,执行词法分析的程序即为词法分析程序,在程序中先判断这个语句中的每个单元为关键字、常数、运算符、界符,对不同的单词符号给出不同编码形式的编码用以区分之,识别出源程序中的单词并以二元式的形式输出。
三、实验要求1、该个词法分析器要求至少能够识别以下几类单词:a.关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写;b.标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*;c.常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等。
d.专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示。
词法分析器实验报告
C_minus语言词法分析器的设计一实验目的设计一个简单的词法分析器,从而进一步加深对词法分析器工作原理的理解.二实验内容编制一个能够分析整数、标识符、主要运算符和主要关键字的词法分析器。
三实验要求1、该个词法分析器要求至少能够识别以下几类单词:关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写;标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*;常数:NUM = digit digit*(.digit digit* |ε)(e(+ |— |ε) digit digit* |ε),letter = a|..|z|A|。
.|Z|,digit = 0|..|9,包括整数,如123等;小数,如123。
45等;科学计数法表示的常数,如1。
23e3,2.3e—9等;专用符号:+ — * / < <= > 〉= == != = ; ,()[ ] { } /* */;2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示.3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
四实验环境PC微机;Windows操作系统;本次实验采用visual C++程序集成环境,采用C语言编写。
五实验步骤(一)构造单词的分类表单词的分类:构造上述语言中的各类单词符号及其分类码表如下:词法分析器实验报告(二)实验原理图(三)主要实验代码:1。
全局变量:char prog[80]={'\0’},//存放程序char token[8]; //存放构成单词符号的字符串char ch;//输入字符int syn,//存放单词字符的种别码sum, //存放整数型单词p, //p是缓冲区prog的指针n=-1;//记录标识符在符号表中的位置char *keyword[6]={"else”,"if",”int","while","void”,”return"};2.main函数2.1输入源程序:do{ch=getchar();prog[p++]=ch;}while(ch!='#');2.2循环调用子函数:do{scaner();switch(syn){case 11: break;case -1: printf("\n ERROR;\n”);break;case 10: printf(”(%d,%s的符号表入口地址%d)\n”,syn,token,n);break;default: printf("(%d,%s)\n",syn,token);}}while(syn!=0);3。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编译原理实验报告题目: C_minus语言词法分析器学 院 计算机科学与技术 专 业 xxxxxxxxxxxxxxxx学 号 xxxxxxxxxxxx姓 名 xxxx指导教师 xxxx20xx 年xx 月xx 日C_minus 语言词法分析器一、实验目的1.理解词法分析器的设计方法:利用DFA 编写相应的程序。
装订线2.掌握手工编写词法分析程序的方法。
3.复习熟悉以前学过的编程语言4.通过实验了解编译器词法分析的工作原理二、实验原理1.文法的概念,DFA的表示方法。
2.词法分析程序的输出和输入:词法分析程序的功能是读入源程序,输出单词符号。
单词符号是程序设计语言的比本语法符号,程序设计语言的单词符号一般分为如下几种:关键字,标示符,常数,运算符,界符,单词的输出是二元式的形式,需要知道二元式的表示方法,把得到的二元式写入输出文件。
转化图如下:3.熟悉单词的描述工具,如正规文法,正规式,以及知道正规文法和正规式的等价性以及他们之间的互相转化。
熟悉把正规文法转化为正规式,把正规式转化为NFA以及把NFA转为相应的DFA,最后再把DFA简化,DFA的状态转化为相应的子程序,最后得到词法分析器语言的基本语法。
三、实验要求1、该个词法分析器要求至少能够识别以下几类单词:关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写;标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*;常数:NUM = digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123等;小数,如等;科学计数法表示的常数,如,等;专用符号:+ - * / < <= > >= == != = , ( ) [ ] { } /* */;2、分析器的输入为由上述几类单词构成的程序,输出为该段程序的机内表示形式,即关键字、运算符、界限符变为其对应的机内符,常数使用二进制形式,标识符使用相应的标识符表指针表示。
3、词法分析器应当能够指出源程序中的词法错误,如不可识别的符号、错误的词法等。
四、实验结果(程序)及分析#include<>#include<>#include<>#define N 100typedef struct {char name[30];int code;int addr;}token;ame[j]){h=0;} else{h=1;break;}}if(h==0)break;}if(h==0) {=key[i].code;output_1();} else{strcpy(symboltable[addr_count].name,;symboltable[addr_count].code=10;symboltable[addr_count].addr=addr_count;addr_count++;output_2();}}void isOthers(){char ch1;int i;for(i=0;i<30;i++)[i]='\0';switch(ch){case '+':{[0]='+';=13;=-1;output_others();break;}case '-': {[0]='-';=14;=-1;output_others();break;}case '*': {=15;=-1;output_others();break;}case '/':{[0]='/';=16;=-1;output_others();break;}case'<':{ch1=fgetc(source);if(ch1=='='){[0]='<';[1]='=';=17;output_others();break;} else {fseek(source,-1,1);[0]='<';=18;=-1;output_others();break;}}case'>': {ch1=fgetc(source);if(ch1=='=') {[0]='>';[1]='=';=19;output_others();break;}else{fseek(source,-1,1);[0]='>';=20;output_others();break;}case'=': {ch1=fgetc(source);if(ch1=='='){[0]='=';[1]='=';=21;=-1;output_others();break;}else {[0]='=';=22;=-1;output_others();fseek(source,-1,1);break;}}case '!': {ch1=fgetc(source);if(ch1=='='){[0]='!';[1]='=';=23;=-1;output_others();break;}else{fseek(source,-1,1);[0]='!';=24;=-1;output_others();break;}}case ';': {[0]=';';=25;=-1;output_others();break;}case ',': {[0]=',';=26;=-1;output_others();}case '(': {int i=ftell(source);char ch1=ch;char ch2;while(ch!=')') {ch=fgetc(source);}if(ch==')') {[0]=ch1;[1]=ch;=27;=-1;output_others();fseek(source,i,0);ch2=fgetc(source);ch2=fgetc(source);break;}else{error_count++;error(1);fseek(source,i,0);ch2=fgetc(source);ch2=fgetc(source);break;}}case '{':{[0]='{';=28;=-1;output_others();break;}case '}':{[0]='}';=28;=-1;output_others();break;}case '[':{[0]='[';=29;=-1;output_others();break;}case ']': {[0]=']';=29;=-1;output_others();break;}case'10': {lineof++;break;}}}void Iszhushi() {char ch1;ch1=ch;ch=fgetc(source);if(ch=='*') {for(;;){ch=fgetc(source);if(ch==EOF) {error(2);break;}if(ch=='*') {ch1=ch;ch=fgetc(source);if(ch=='\\') {ch=fgetc(source);break;}}}}else{error_count++;error(2);}}void isnumber() {int k=0;void output_number();while(ch>='0'&& ch<='9'){[k++]=ch;ch=fgetc(source);}=11;output_number();}void output_1() {printf("关键字:<%s,%d>",,;putchar(10);fprintf(keytxt,"<%s,%d>",,;}void output_2() {printf("标识符地址:<%s,%d>",,addr_count);putchar(10);fprintf(badgetxt,"<%s,%d>",,addr_count);}void output_others() {printf("其它单词:<%s,%d>",,;putchar(10); fprintf(othertxt,"<%s,%d>",,;}void error(int i) {switch(i){case 1: printf("界符发生错误,发生在第%d行/n",lineof);case 2: printf("注释发生错误,发生在第%d行/n",lineof);}}void output_number() {printf("常数<%s,%d>\n",,;fprintf(number,"<%s,%d>",,;}实验结果分析,程序运行结果截图:关键字输出文件:标识符输出文件:数字的输出文件其它单词输出文件:。