词法分析器课程设计报告
- 格式:doc
- 大小:311.50 KB
- 文档页数:13
c词法分析器实验报告篇一:词法分析器设计实验报告计算机与信息学院(信息工程系)编译原理实验报告专业班级课程教学班任课教实验指导教师实验地点XX ~XX学年第一学期实验一词法分析器设计一、实验目的通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。
二、实验内容用 VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。
通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。
以下是实现词法分析设计的主要工作:(1)从源程序文件中读入字符。
(2 (3 (4(属性值——token 的机内表示)(5)如果发现错误则报告出错 7(6三、实验流程图四、实验步骤12、编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计的词法分析程序;直至能够得到完全满意的结果。
3、书写实验报告;实验报告正文的内容:五、实验结果篇二:C语言词法分析器实验报告计算机科学与工程系编译原理课程设计实验报告姓名:__ ******__ 学号_ *******__ 年级专业及班级___08计算机科学与技术成绩- 1 -- 2 -- 3 -- 4 -- 5 -篇三:词法分析器实验报告实验报告实验题目:词法分析器院系班级:计科系0901班姓名学号: XX210603实验时间:XX-10-21设计。
编制并调试一个词法分析程序,加深对词法分析原理的理解。
实验要求设计出一个简单的词法分析程序,能够识别关键字(包含begin、if、end、 while、else、 then)、标识符、数字及数种符号(+、-、*、/、(、)、:、=、:=、#、>、、=、;)。
返回并打印各类字符所对应的种类编码及该字符所组成的二元组。
词法分析器实验报告⼀、实验⽬的通过设计⼀个词法分析程序,对词法进⾏分析,加强对词法的理解,掌握对程序设计语⾔的分解和理解。
⼆、实验内容和要求在原程序中输⼊源代码对字符串表⽰的源程序从左到右进⾏扫描和分解根据词法规则识别出⼀个⼀个具有独⽴意义的单词符号以供语法分析之⽤发现词法错误,则返回出错信息在源程序中,⾃动识别单词,把单词分为五种,并输出对应的单词种别码。
1. 识别关键字:main if int for while do return break continue,该类的单词码为1.2. 识别标识符:表⽰各种名字,如变量名、数组名、函数名等,如char ch, int syn, token,sum,该类的单词码为2.3. 运算符:+、-、*、/、=、>、<、>=、<=、!=4. 分隔符:,、;、{、}、(、)5. 常数,例:123各种单词符号对应的种别码。
输出形式:⼆元式– (单词种别,单词⾃⾝的值)单词种别,表明单词的种类,语法分析需要的重要信息– 整数码关键字、运算符、界符:⼀符⼀码标识符:10, 常数:11单词⾃⾝的值– 标识符token、常数sum– 关键字、运算符、界符token三、实验⽅法、步骤及结果测试1.源程序#include <stdio.h>#include <string.h>char string[80],simbol[8],ch;int wordID,index,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(void);main(){int index=0;printf("请输⼊代码,并以串#号键结束:\n");do{scanf("%c",&ch);string[index++]=ch;}while(ch!='#');index=0;do{scaner();switch(wordID)case11:printf("( %-10d%5d )\n",sum,wordID);break;case -1:printf("错误\n");return0;break;default:printf("( %-10s%5d )\n",simbol,wordID);break;}}while(wordID!=0);return0;}void scaner(void){sum=0;for(m=0;m<8;m++)simbol[m++]= NULL;ch=string[index++];m=0;while((ch=='')||(ch=='\n'))ch=string[index++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))//判断输⼊的字符是否为英⽂字母 {while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))){simbol[m++]=ch;ch=string[index++];}index--;wordID=10;for(n=0;n<6;n++)if(strcmp(simbol,rwtab[n])==0){wordID=n+1;break;}}else if((ch>='0')&&(ch<='9'))//判断输⼊的字符是否为数字{while((ch>='0')&&(ch<='9')){sum=sum*10+ch-'0';ch=string[index++];}index--;wordID=11;}else{switch(ch)//通过循环判断输⼊的字符是否为运算符{case'<':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=22;simbol[m++]=ch;}else{wordID=20;index--;}break;case'>':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=24;simbol[m++]=ch;else{wordID=23;index--;}break;case'+':simbol[m++]=ch;ch=string[index++];if(ch=='+'){wordID=17;simbol[m++]=ch;}else{wordID=13;index--;}break;case'-':simbol[m++]=ch;ch=string[index++];if(ch=='-'){wordID=29;simbol[m++]=ch;}else{wordID=14;index--;}break;case'!':ch=string[index++];if(ch=='='){wordID=21;simbol[m++]=ch;}else{wordID=31;index--;}break;case'=':simbol[m++]=ch;ch=string[index++];if(ch=='='){wordID=25;simbol[m++]=ch;}else{wordID=18;index--;}break;case'*':wordID=15;simbol[m++]=ch;break;case'/':wordID=16;simbol[m++]=ch;break;case'('://判断输⼊的字符是否为分隔符 wordID=27;simbol[m++]=ch;break;case')':wordID=28;simbol[m++]=ch;break;case'{':wordID=5;simbol[m++]=ch;break;case'}':wordID=6;simbol[m++]=ch;break;case';':wordID=26;simbol[m++]=ch;break;case'\"':wordID=30;simbol[m++]=ch;break;case'#':wordID=0;simbol[m++]=ch;break;case':':wordID=17;simbol[m++]=ch;break;default:wordID=-1;break;}}simbol[m++]='\0'; }四.运⾏结果及分析。
计算机网络课程设计报告班级:计1102姓名:杨勇学号: 41155047词法分析器:一、实验目的调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验要求1、待分析的简单语言的词法(1)关键字:begin if then while do end所有关键字都是小写。
(2)运算符和界符::= + –* / <<= <>>>= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)*NUM=digit digit *(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码3、词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
三、C语言程序源代码:#include <stdio.h>#include <string.h>char prog[80],token[8],ch;int syn,p,m,n,sum;char *rwtab[6]={"begin","if","then","while","do","end"}; scaner();main(){p=0;printf("\n please input a string(end with '#'):/n");do{scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11:printf("( %-10d%5d )\n",sum,syn);break;case -1:printf("you have input a wrong string\n");getch();exit(0);default: printf("( %-10s%5d )\n",token,syn);break;}}while(syn!=0);getch();}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;ch=prog[p++];m=0;while((ch==' ')||(ch=='\n'))ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0) { syn=n+1;break;}}else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':token[m++]=ch;ch=prog[p++];if(ch=='=')token[m++]=ch;}else{ syn=20;p--;}break;case '>':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;p--;}break;case '+': token[m++]=ch; ch=prog[p++];if(ch=='+')token[m++]=ch;}else{ syn=13;p--;} break;case '-':token[m++]=ch; ch=prog[p++];if(ch=='-'){ syn=29;token[m++]=ch;}else{ syn=14;p--;} break;case '!':ch=prog[p++];{ syn=21;token[m++]=ch;}else{ syn=31;p--;}break;case '=':token[m++]=ch; ch=prog[p++];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;p--;}break;case '*': syn=15;token[m++]=ch; break;case '/': syn=16; token[m++]=ch; break;case '(': syn=27; token[m++]=ch; break;case ')': syn=28; token[m++]=ch; break;case '{': syn=5; token[m++]=ch; break;case '}': syn=6; token[m++]=ch; break;case ';': syn=26; token[m++]=ch; break;case '\"': syn=30; token[m++]=ch;break;case '#': syn=0;token[m++]=ch;break;case ':':syn=17;token[m++]=ch;break;default: syn=-1;break;}token[m++]='\0';}三、实验结果:1、给定源程序begin x:=9; if x>0 then x:=2*x+1/3; end#输出结果2、源程序(包括上式未有的while、do以及判断错误语句):beginx<=$;whilea<0dob<>9-x;end#输出结果四、总结分析:通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,根据识别语言单词的状态转换图,使用某种高级语言(例如C++语言)直接编写此法分析程序。
词法分析器实验报告词法分析器实验报告一、引言词法分析器是编译器中的重要组成部分,它负责将源代码分解成一个个的词法单元,为之后的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,以深入理解其工作原理和实现过程。
二、实验目标本实验的目标是设计和实现一个能够对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运算符:;```可以看到,词法分析器能够正确地将代码分解成各种词法单元,并输出其对应的类别。
编译原理课程设计1一、题目:词法分析器二、运行环境:JAVA jdk1.6.0_21三、设计思路:编译程序的工作过程一般划分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。
作为本次课程设计的词法分析器的主要任务是,对输入的源程序字符串进行扫描和分解,识别出一个个的单词,如基本字(include、if、while、for等),标识符、常数、算符和界符。
本次课程设计词法分析我选取的目标语言为C语言。
关于种别码的分配,我对关键字采用一字一种,对运算符采用一符一种,对界符采用一符一种,整型常量为一种,浮点常量为一种,字符常量为一种,字符串常量为一种。
(详情参加附录1)本次词法分析器工作的第一步是输入源程序文本。
通过调用预处理子程序去除程序两端多余的空格、注释,再将处理得到的串存放在一个缓冲区中。
第二步是对关键字、标示符、数字以及算符和界符的识别过程,并返回识别出的单词的种别码和内容(单词值,种别码),在过程中进行必要的出错处理。
第三步即将所识别出来的单词及种别码输出到文件保存。
四、基本工具UML及JAVA语言五、状态转换图:六、程序源码:import java.util.ArrayList;import java.io.*;//记法分析器类class Lex{char ch[] = new char[300];String token;int flag;ArrayList<String> buffer = new ArrayList<String>();ArrayList<String> errorqueue = new ArrayList<String>();ArrayList<String> queue = new ArrayList<String>();int buffer_current,buffer_advance,index_queue,index_error,line,buffersize;public Lex(){buffer_current=buffer_advance=index_queue=index_error = buffersize = 0;line = 1;flag = 0;}//判断是否为字母public boolean isletter(char cc){if ((cc>='a'&&cc<='z')||(cc>='A'&&cc<='Z')){return true;}else{return false;}}//判断是否为数字public boolean isdigit(char cc){if (cc>='0'&&cc<='9'){return true;}else{return false;}}//预处理子程序,读入源程序,并装入bufferpublic void prepare(){int k ;String sub;try{FileReader filein = new FileReader("in.txt");filein.read(ch);String str = new String(ch);k = 0;while(k<300){buffer.add(sub);buffersize++;k++;filein.close();}}catch (Exception e){String err = e.toString();System.out.println(err);}}//result_out函数将所有识别了的单词输出到文件out.txt public void result_out(){int k;if (index_queue == 0){System.out.println("The queue is empty!");return;}try{FileWriter fileout = new FileWriter("out.txt");fileout.write("\t符号(值)\t种别码\n");for (k =0; k<index_queue ; k++ ){fileout.write(queue.get(k));}fileout.close();}catch (Exception e){String err = e.toString();System.out.println(err);}}//error_out函数将所有识别了的错误情形输出到文件error.txtpublic void error_out(){int k;if (index_error == 0){System.out.println("The errorqueue is empty!");return;}try{FileWriter errorout = new FileWriter("error.txt");for (k =0; k<index_error ; k++ ){errorout.write(queue.get(k));}errorout.close();}catch (Exception e){String err = e.toString();System.out.println(err);}}//判断是否为保留字public int isreserve(String s){String str[] = {"define","include","char","double","enum","float","int","long","short","signed","struct","union","unsigned","void","for","do","while","break","continue","if", "else","goto","switch","case","default","return","auto","extern","register","static","const","sizeof","typedef","volatile"};int k;for ( k =0 ; k < 34 ; k++ ){if (str[k].equals(s)){return (k+4);}}return 0;}//往queue队列添加一个新识别的单词public void insert_queue(String s){queue.add(s);index_queue++;}//往errorqueue队列添加一个新发现的错误public void insert_error(String s){errorqueue.add(s);index_error++;}//读掉空格public void space(){String s;do{s = queue.get(buffer_advance);if (s.equals(" ")){if (buffer_advance+1 == buffersize){flag = 1;return;}buffer_advance++;}else{break;}}while(true);buffer_current = buffer_advance;}// 读掉形如的//.... \n 注释public void comment1(){String s;do{s = queue.get(buffer_advance);if (s.equals("\n")){line++;break;}{if (buffer_advance+1 == buffersize){flag = 1;return;}buffer_advance++;}}while(true);buffer_current = buffer_advance;}// 读掉形如的/*.... */ 注释public void comment2(){String s1,s2;do{s1 = queue.get(buffer_advance);s2 = queue.get(buffer_advance+1);if (s1.equals("\n")){buffer_advance++;line++;}else if (s1.equals("*")&&s2.equals("/")){buffer_advance = buffer_advance + 2;break;}else{if (buffer_advance+1 == buffersize){flag = 1;return;}buffer_advance++;}}while(true);buffer_current = buffer_advance;}//实现单词识别public void dfa(){int flag2;String s1,s2;prepare();while ( flag == 0 ){flag2 = 0;token = "";//存放识别出来的单词space();do{s1 = queue.get(buffer_advance);s2 = queue.get(buffer_advance+1);if (s1.equals("/")&&s2.equals("/")){if (buffer_advance+2 == buffersize){flag = 1;break;}buffer_advance = buffer_advance+2;comment1();}else if (s1.equals("/")&&s2.equals("*")){if (buffer_advance+2 == buffersize){flag = 1;break;}buffer_advance = buffer_advance+2;comment2();}else if (s1.equals("\n")){if (buffer_advance+1 == buffersize){flag = 1;break;}buffer_advance++;line++;}else{break;}space();}while (true);//下面是数值常量识别主要是实数和整数的识别if (isdigit(s1.charAt(0))){flag2 = 2;token = token + s1;buffer_advance++;s1 = buffer.get(buffer_advance);while (isdigit(s1.charAt(0))){token = token + s1;if (buffer_advance+1 != buffersize){buffer_advance++;s1 = buffer.get(buffer_advance);}else{insert_queue("\t"+token+"\t2\n");break;}}/*如果数字后碰到小数点,小数点后不是数字,则要捕捉错误异常;如果还是数字,则和上面的方法一样,将一串数字连为一个实数*/if(s1.equals(".")){flag = 3;token = token + s1;buffer_advance++;s1 = buffer.get(buffer_advance);if (!isdigit(s1.charAt(0))){insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");continue;}while (isdigit(s1.charAt(0))){token = token + s1;if (buffer_advance+1 != buffersize){buffer_advance++;s1 = buffer.get(buffer_advance);}else{insert_queue("\t"+token+"\t3\n");break;}}}//如果碰到科学计数法中的e,要取出它面的符号,然后再取出数值部分if (s1.equalsIgnoreCase("e")){token = token + s1;buffer_advance++;if (buffer_advance!= buffersize){s1 = buffer.get(buffer_advance);}else{insert_queue("\t"+token+"\t3\n");break;}if (s1.equals("-")){token = token + s1;buffer_advance++;if (buffer_advance != buffersize){s1 = buffer.get(buffer_advance);}else{insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");break;}}else if (s1.equals("+")){token = token + s1;buffer_advance++;if (buffer_advance != buffersize){s1 = buffer.get(buffer_advance);}else{insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");break;}}if (!isdigit(s1.charAt(0))){insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");continue;}while (isdigit(s1.charAt(0))){flag = 3;token = token + s1;buffer_advance++;if (buffer_advance != buffersize){s1 = buffer.get(buffer_advance);}else{insert_queue("\t"+token+"\t3\n");continue;}}}//科学eif(flag == 2){insert_queue("\t"+token+"\t2\n");continue;}if(flag == 3){insert_queue("\t"+token+"\t3\n");continue;}}//数字识别//下面是标志符及保留字识别if (isletter(s1.charAt(0))||s1.charAt(0)=='_'){token = token +s1;int t;do{buffer_advance++;if (buffer_advance!=buffersize){s1 = buffer.get(buffer_advance);}else{break;}if (isletter(s1.charAt(0))||s1.charAt(0)=='_'||isdigit(s1.charAt(0))){token = token +s1;}else{break;}}while (true);if ((t = isreserve(token))!=0){insert_queue("\t"+token+"\t"+t+"\n");}else{insert_queue("\t"+token+"\t71\n");}continue;}// if (isletter(s1.charAt(0))||s1.charAt(0)=='_')//下面是识别字符常量如'a'if (s1.charAt(0) == '\''){token = token + s1;if (buffer_advance +2>=buffersize){insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");continue;}else{buffer_advance++;s1 = buffer.get(buffer_advance);token = token + s1;}s2 = buffer.get(buffer_advance);if (s2.charAt(0)== '\''){token = s1;buffer_advance++;insert_queue("\t"+token+"\t0\n");}else{insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");}continue;}// 下面是识别字符串常量if (s1.charAt(0) == '\"'){do{buffer_advance++;s1 = queue.get(buffer_advance);if (s1.equals("\"")){insert_queue("\t"+token+"\t1\n");buffer_advance++;break;}else{if (buffer_advance+1 == buffersize){insert_error("\n程序第("+line+")行有错误错误单词为:"+token+"\n");flag = 1;break;}token = token + s1;}}while(true);continue;}//下面是识别运算符+ 或++if (s1.charAt(0)=='+'){token =token + s1;buffer_advance++;{insert_queue("\t+"+"\t38\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("+")){buffer_advance++;insert_queue("\t++"+"\t46\n");}else{insert_queue("\t+"+"\t38\n");}}continue;}//下面是识别运算符- 或-- 或->if (s1.charAt(0)=='-'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t-"+"\t39\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("-")){buffer_advance++;insert_queue("\t--"+"\t47\n");}else if (s1.equals(">")){buffer_advance++;insert_queue("\t->"+"\t68\n");}else{}}continue;}//下面是识别运算符* 或者**if (s1.charAt(0)=='*'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t*"+"\t40\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("*")){buffer_advance++;insert_queue("\t**"+"\t50\n");}else{insert_queue("\t*"+"\t40\n");}}continue;}//下面是识别运算符/if (s1.charAt(0)=='/'){insert_queue("\t/"+"\t41\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别运算符& 或者&&if (s1.charAt(0)=='&'){token =token + s1;if (buffer_advance == buffersize){insert_queue("\t&"+"\t42\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("&")){buffer_advance++;insert_queue("\t&&"+"\t48\n");}else{insert_queue("\t&"+"\t42\n");}}continue;}//下面是识别运算符| 或者||if (s1.charAt(0)=='|'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t|"+"\t43\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("|")){buffer_advance++;insert_queue("\t||"+"\t49\n");}else{insert_queue("\t|"+"\t43\n");}}continue;//下面是识别运算符! 或者!=if (s1.charAt(0)=='!'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t!"+"\t44\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("=")){buffer_advance++;insert_queue("\t!="+"\t54\n");}else{insert_queue("\t!"+"\t44\n");}}continue;}//下面是识别运算符%if (s1.charAt(0)=='%'){insert_queue("\t%"+"\t45\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别运算符> 或者>=if (s1.charAt(0)=='>'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t>"+"\t51\n");}else{s1 = buffer.get(buffer_advance);if (s1.equals("=")){buffer_advance++;insert_queue("\t>="+"\t56\n");}else{insert_queue("\t>"+"\t51\n");}}continue;}//下面是识别运算符< 或者<=if (s1.charAt(0)=='<'){token =token + s1;buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t<"+"\t52\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("=")){buffer_advance++;insert_queue("\t<="+"\t57\n");}else{insert_queue("\t<"+"\t52\n");}}continue;}//下面是识别运算符= 或者==if (s1.charAt(0)=='='){buffer_advance++;if (buffer_advance == buffersize){insert_queue("\t="+"\t53\n");break;}else{s1 = buffer.get(buffer_advance);if (s1.equals("=")){buffer_advance++;insert_queue("\t=="+"\t55\n");}else{insert_queue("\t="+"\t53\n");}}continue;}//下面是识别界符(if (s1.charAt(0)=='('){insert_queue("\t("+"\t58\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符)if (s1.charAt(0)==')'){insert_queue("\t)"+"\t59\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符#insert_queue("\t#"+"\t60\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符;if (s1.charAt(0)==';'){insert_queue("\t;"+"\t61\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符,if (s1.charAt(0)==','){insert_queue("\t,"+"\t62\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符:if (s1.charAt(0)==':'){insert_queue("\t:"+"\t63\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符{insert_queue("\t{"+"\t64\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符}if (s1.charAt(0)=='}'){insert_queue("\t}"+"\t65\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符[if (s1.charAt(0)=='['){insert_queue("\t["+"\t66\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符]if (s1.charAt(0)==']'){insert_queue("\t]"+"\t67\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}//下面是识别界符.if (s1.charAt(0)=='.')insert_queue("\t."+"\t69\n");buffer_advance++;if (buffer_advance == buffersize){break;}continue;}}//while(flag == 1)if (index_queue>0){result_out();}if (index_error>0){error_out();}}}public class startLex{public static void main ( String args[] ){Lex l = new Lex();l.dfa();}}七、运行结果:运行前源程序存放在in.txt中,如图(1)所示,运行后得到的识别单词结果存放在out.txt中,如图(2)所示,识别过程中发现的错误存放在error.txt中,如图(3)所示。
词法分析器的实验报告词法分析器的实验报告引言:词法分析器是编译原理中的重要组成部分,它负责将源代码中的字符序列转换为有意义的词法单元,为后续的语法分析提供基础。
本实验旨在设计和实现一个简单的词法分析器,并对其进行测试和评估。
实验设计:1. 词法规则设计:在开始实验之前,我们首先需要设计词法规则,即定义源代码中的合法词法单元。
例如,对于一门类C的语言,我们可以定义关键字(如if、while、int等)、标识符、运算符(如+、-、*等)、分隔符(如()、{}等)等。
2. 有限自动机(DFA)的设计:基于词法规则,我们可以设计一个有限自动机,用于识别和分析源代码中的词法单元。
有限自动机是一个状态转换图,其中每个状态代表一种词法单元,而边表示输入字符的转换关系。
3. 实现代码:根据有限自动机的设计,我们可以使用编程语言(如Python、C++等)实现词法分析器的代码。
代码的主要功能包括读取源代码文件、逐个字符进行词法分析、识别和输出词法单元。
实验过程:1. 词法规则设计:我们以一门简单的算术表达式语言为例,设计了以下词法规则:- 数字:由0-9组成的整数或浮点数。
- 运算符:包括+、-、*、/等。
- 分隔符:包括括号()和逗号,。
- 标识符:以字母开头,由字母和数字组成的字符串。
2. 有限自动机(DFA)的设计:我们基于词法规则,设计了一个简单的有限自动机。
该自动机包含以下状态:- 初始状态:用于读取和识别源代码中的字符。
- 数字状态:用于识别和输出数字。
- 运算符状态:用于识别和输出运算符。
- 分隔符状态:用于识别和输出分隔符。
- 标识符状态:用于识别和输出标识符。
3. 实现代码:我们使用Python编程语言实现了词法分析器的代码。
代码主要包括以下功能:- 读取源代码文件。
- 逐个字符进行词法分析,根据有限自动机的设计进行状态转换。
- 识别和输出词法单元。
实验结果:我们对几个测试样例进行了词法分析,并对结果进行了评估。
编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
编译原理课程设计报告题目:学院:教师::学号:班级:评分:签字:编译原理课程设计一:设计c语言的词法分析器一、实验目的了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程,加深对词法原理的理解。
二、实验要求了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。
三、实验设计3.1.单词分类及表示3.1.1 C语言的子集分类(1)标识符:以字母开头的字母数字串(2)整数或浮点型。
(3)保留字:for,while,do,else,if,static,int,sizeof,break,continue(4)运算符:+,-,*,/,%,>,<,=,!=,==,<=,>=,!,&,&&,||;(5)界符:"(",")",",",":",";","{","}"3.1.2单词二元组(单词分类号、单词自身值)3.2 词法分析器的设计3.2.1算法设计3.2.1.1概要设计从文件中逐个读取字符,只要这五大类的状态序列则继续读取,否则回退字符,在对应类别进行查找,输出单元二次组至另一文件夹。
3.2.1.2状态图设计开始打开txt文件读取c语言代码扫描是否读取到相应字符常数?标识符保留字运算符记录标号结束界符?YY Y3.2.2输入输出设计输入:通过文件指针从文件中一个一个读取字符输出:输出单词二元组至文件。
格式为(种别码,值)3.2.3主要函数void Getchar(FILE *fp ) //读入一个字符void GetBC(FILE *fp)//读入一个非空字符void contacat()//连接字符int letter()//判断是否为字母int digit()//判断是否为字母void retract(FILE *fp,char *c)//回退int reserve (char **k)//处理保留字int sysmbol(identifier *id)//处理标识符,查找符号表并存放位置若没有则添加int constant(constnumber *con)//存入常数表,并返回它在常数表中的位置void Tofile(int num, int val, identifier *id, constnumber *con, FILE *fw)//写到文件void WordAnalyze(char **k,char *c, char **CODE, identifier *id, constnumber *con, FILE *fp, FILE *fw)//词法分析函数四、结果测试文件输入int main(){int a=1,b=3;if(a>1)b=b-2;}输出结果:结论:程序输出结果与期望输出结果相符。
实验报告学号:姓名:专业:计算机科学与技术班级:2班第9周三、根据DFA编写词法分析器#include<fstream>#include<string>#include<iostream>using namespace std;static int rowCounter = 1;//静态变量,用于存储行数static bool bracketExist = false;//判断注释存在与否,false为不存在class Lex{public:ofstream output;string line = "";Lex(string inputLine){line = inputLine;scan(Trim(line));rowCounter++;}string Trim(string &str)//函数用于去除每行前后空格{int s = (" \t");int e = (" \t");str = (s, e - s + 1);str += "\0";return str;}void scan(string inputLine){ofstream output;("", ios::app);string line = inputLine;int i = 0;string str = "";int temp;string token = "";output << rowCounter << ": " << line << endl;//输出每行while (line[i] != '\0')//根据DFA扫描并判断{if (line[i] == '{')//注释{bracketExist = true;}if (bracketExist == true){output << "\t" << rowCounter << ": ";while (line[i] != '}'){output << line[i];//不处理,直接输出if (line[i + 1] != NULL){i++;}elsebreak;}if (line[i] == '}')//注释结束{output << line[i]<<endl;bracketExist = false;}}if (bracketExist == false){//数字while (isdigit(line[i])){temp = temp * 10 + line[i];if (!isdigit(line[i + 1])){output << "\t" << rowCounter << ": " << "NUM, val= " << temp - '0' << endl;}if (line[i + 1] != NULL&&isdigit(line[i + 1]))i++;elsebreak;}temp = 0;//符号while (!(isdigit(line[i]) || (line[i] >= 'a'&&line[i] <= 'z') ||(line[i] >= 'A'&&line[i] <= 'Z') || line[i] == ' ' || line[i] == '{' || line[i] == '}')) {token = token + line[i];if (isdigit(line[i + 1]) || (line[i + 1] >= 'a'&&line[i + 1] <= 'z') || (line[i + 1] >= 'A'&&line[i + 1] <= 'Z') || line[i + 1] == ' ' || line[i + 1] == '{' || line[i + 1] == '}' || line[i + 1] == NULL){if (isToken(token)){output << "\t" << rowCounter << ": " << token << endl;}else{int j = 0;while (token[j] != '\0'){output << "\t" << rowCounter << ": " << token[j] << endl;j++;}}}else{i++;continue;}if (line[i + 1] != NULL)i++;elsebreak;}token = "";//字母while ((line[i] >= 'a'&&line[i] <= 'z') || (line[i] >= 'A'&&line[i] <= 'Z')){str = str + line[i];if (!((line[i + 1] >= 'a'&&line[i + 1] <= 'z') || (line[i + 1] >='A'&&line[i + 1] <= 'Z'))){if (isResearvedWord(str)) //判断是否是保留字{output << "\t" << rowCounter << ": " << "Reversed Word: " << str << endl;break;}else{output << "\t" << rowCounter << ": " << "ID, name= " << str << endl;break;}}if (line[i + 1] != NULL)i++;}str = "";if (line[i + 1] != NULL){i++;}elsebreak;}if (line[i + 1] == NULL){if (line[i] == ';')output << "\t" << rowCounter << ": " << line[i];break;}}//清空,以备下一行读取line = "";str = "";temp = 0;token = "";output << endl;();}bool isResearvedWord(string s)//存储保留字,并判断{string reservedWord[8] = { "if", "then", "else", "end", "repeat", "until", "read", "write" };bool judge = false;for (int i = 0; i < 8; i++){if (s == reservedWord[i]){judge = true;break;}}return judge;}bool isToken(string s)//存储符号,并判断{string token[10] = { "+", "-", "*", "/", "=", "<", "(", ")", ";", ":=" };bool judge = false;for (int i = 0; i < 10; i++){if (s == token[i]){judge = true;break;}}return judge;}};int main(){ifstream input;("");string line[50];int i = 0;while (getline(input, line[i])){//cout << line[i] << endl;i++;}();cout << endl << endl << "Reading source file completed!!" << endl;int j = 0;remove("");for (j = 0; j < i; j++){Lex lex(line[j]);}cout << endl << endl << "Writing file completed!!" << endl << endl << endl;return 0;}四、重要数据结构string line[]:用于存储每一行的字符,并逐个读取分析。
精选课程设计任务书引言 (4)第一章概述 (5)1.1设计内容 (5)1.2设计要求 (5)第二章设计的基本原理 (6)2.1 (6)2.2 (6)第三章程序设计 (7)3.1 总体方案设计 (7)3.2 各模块设计 (8)第四章程序测试 (9)4.1一般测试4.2出错处理测试第五章结论 (10)参考文献 (10)附录程序清单 (11)引言《编译原理》是国内外各高等院校计算机科学技术类专业,特别是计算机软件专业的一门重要专业课程。
该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。
由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。
为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。
编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。
词法分析阶段是编译过程的第一个阶段,是编译的基础。
这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。
词法分析程序实现这个任务。
词法分析程序可以使用 Lex 等工具自动生成。
从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token ),把源程序变为等价的标记串序列。
执行词法分析的程序称为词法分析器,也称为扫描器。
词法分析是所有分析优化的基础,涉及的知识较少,如状态转换图等,易于实现。
本次课程设计,我的选题是词法分析, C++ 代码实现。
第一章概述1.1 设计内容对 C 语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
1.2设计要求利用该词法分析器完成对源程序字符串的词法分析。
2009-2010学年第二学期《编译原理》课程设计报告学院(系):班级:学生姓名:学号:指导教师:时间:2010 年6 月目录1. 课程设计的目的 (1)2.课程设计的内容及要求 (1)2.1.课程设计内容 (1)2.2.课程设计要求 (2)2.3.运行环境 (3)2.4.程序的不足 (3)3.问题分析及相关原理介绍 (3)3.1. 编译程序介绍 (3)3.2.各部分的功能介绍及分析 (3)3.3. 算法实现及模拟 (4)3.3.1总体流程图 (4)3.3.2详细的流程图 (5)4.设计思路及关键问题的解决方法 (7)4.1.设计思路及关键问题 (7)4.1.1处理时机 (7)4.1.2一个棘手问题 (8)4.2.解决方法 (8)5.结果及测试分析 (8)5.1.待分析程序的部分内容 (8)5.2.运行结果 (9)6.总结 (10)6.1.设计过程 (10)6.2.困难与收获 (11)参考文献 (11)附录 (11)1.课程设计的目的通过课程设计实践,树立正确的设计思想,巩固所学编程语言基本知识,增进C语言编辑基本功;综合运用所学的理论知识,进一步理解高级语言在计算机中的执行过程,加深对编译原理中重点算法和编译技术的理解;掌握课程设计的一般方法与步骤,深入掌握课程设计的基本理论、方法和步骤,提高自己的编程能力,培养好的程序设计风格。
通过课程设计,真正掌握设计和构造编译程序的基本原理和常用的编译技术,具备系统软件调试能力和开发能力,培养分析问题和解决问题的能力。
同时通过某种编程语言的应用,具备初步的Windows环境下的编程思想。
完成本课程设计的项目——词法分析器,理解词法分析在编译程序中的作用,加深对有穷自动机模型的理解,掌握词法分析程序的实现方法和技术,用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。
2.课程设计的内容及要求2.1.课程设计内容设计内容:完成下述文法所描述的单词符号的词法分析程序。
<标识符>--><字母>|<标识符><字母>|<标识符><数字><无符号整数>--><数字>|<无符号整数><数字><分界符>-->+|-|*|/|;|(|)|{|}|<|<=|==|!=|>=|>|=|<空格><字母>-->a|…|z|A|…|Z<数字>-->0|…|9运用C语言设计词法分析器,由指定文件读入预分析的源程序,经过词法分析器的分析,将结果写入指定文件。
本程序是在Visual Studio环境下,使用C语言作为开发工具。
基于实验任务的内容及目的,实现初步的需求分析,具备词法分析器的基本功能和整体构架。
逐步细化其功能,做到相应模块的具体化。
画出未成熟的流程图,确定整体设计的走向,在一定范围内约束编程活动,确保没有大的问题及缺陷存在,然后通过将来的具体的编程设计完善流程图。
程序设计的具体内容:在实际的设计中,预分析程序保存在文本文件sourcecode.txt中,该文件不能由执行程序自动创建,需要在程序执行前预先提供,程序拥有只读的权限。
程序逐个字符的分析源程序,能够识别标识符,整数,分界符,并分别把分析得到的字符写入相应文档:keyword,words,digit,single,double;其它字符标示为无法识别,记录在error文档中。
程序结束后,将最总结果写入文件Dualistic_formula,该文件的内容包括统计结果(排除重复出现的字符)和二元式。
这七个文件会在程序执行时自动创建,程序结束时,关闭文件,但保留文件的内容,以供查看和检验,测试。
不同类别的字符通过相应的函数模块来分析识别。
普通标识符由函数int word(char ch)来识别,并进一步由函数int keyword(char key[])来分离普通标识符和关键字;数字有函数i nt digit(char ch)来识别;分界符由函数int delimiter(char ch)来识别;其他字符即为非法字符。
该程序中,全局变量共有两个int characters_exist=0和int countoffinal=0。
characters_exist用来判断是否是纯数字,countoffinal用来记录finalresult函数执行的次数。
统计主函数在内,总共16个函数模块,除了前面说到得识别字符的函数外,还有对文件进行操作的函数,对数组操作的函数和实现显示功能的函数。
主函数中有六个文件指针,十一个字符数组,十个实现不同功能的变量。
在程序设计过程中及时注释,方便复读和检测。
2.2.课程设计要求必须运用C语言设计词法分析器,由指定文件读入预分析的源程序,从左至右描源程序的字符串,按照词法规则(正则文法规则)识别出一个个正确的单词,并转换成该单词相应的二元式(种别码、属性值)交给语法分析使用。
本程序规定输出用KeyWord代表关键字,Word代表普通标识符,Digit代表阿拉伯数字,SingleWord代表单分界符,DoubleWord代表双分界符,ERROR代表无法别的字符。
了解和掌握词法分析的方法;编程实现给定源语言程序的词法分析器;利用该分析器扫描源语言程序的字符串,按照给定的词法规则,识别出单词符号作为输出,发现其中的词法错误。
不同类别的字符通过相应的函数模块来分析识别。
针对该程序设计的具体设计:编程实现一个简单的词法分析器,可以对一个文件进行词法分析处理。
程序能够正确识别文法所规定的任何组织形式的字符组合。
例如在连续的分界符中,如何分离出单分界符和双分界符;字符中间的空格如何处理,源程序中往往出现大量连续的空格,若是全部记录下来,没用实际意义,且又浪费时间和空间,这样又如何处理;普通标识符和关键字如何分离出来;数字如何判断,形如123,a123,123a,123=,=123,123#,#123的字符串中,哪些才是整数,其它的又如何舍去。
这些功能都必须实现。
标识符是被分界符分开的,只有在遇到分界符时才能判断前面的字符串是否是标识符;假若非法字符和字母或数字混杂在一起,则这些字母或数字不能形成标识符或整数;这个问题并不复杂,当出现连续的分界符时,棘手的问题才出现。
形如!<==-a,这个分界符字符串该如何分析呢?第一个字符!是单分界符,那么是不是当读到!时就可以立即判断这是一个单分界符呢?不能,因为还有形如字符串!=的可能性,这样一来词法分析器必须拥有展望未来的能力;那么<是不能判断为单分界符的,因为,字符组合<=是双分界符;问题出现了,字符组合==是双分界符,还是单独的认为第二个=是单分界符,这就决定与规定了;既然在读到单分界时不能立即判断其具体归类,那么当读到字符–后,还需要进一步读字符 a ,然后才能判断字符–是否是单分界符,这样一来,就需要在遇到字母或数字时,进行对前面的分界符的判断,这时又需要退两步来分析,也就是需要分析字符 a前面的两个字符才能判断字符 a前面的一个字符是什么属性;这就是说,出现连续的分界符时,需要尾随的其他类的字符来辅助,以判断分界符的具体属性;可是,如果没有其他字符尾随呢,最好的一个分界符该如何处理?还有,如果标识符同样没有其他字符尾随,又该如何处理?分析得到的字符,需要写入文件,保存以供后用。
重复出现的字符不能都作为最后结果存储。
这些多余的字符是在分析时舍去还是在整个源程序被分析完毕后才进一步处理舍的去问题?可以把读到的所有合法字符(出去连续出现的大量空格)暂时保存到相关文件,待分析源程序完毕后,在处理这些文件中的合法字符,舍去重复的,把正确合适的数据写入到另一个文件,形成二元式,该文件才是最后结果。
程序在实现基本功能的同时,以上提出的问题必须小心处理。
在程序设计过程中需要及时注释。
首先整体把握程序设计的架构和内涵,理清需求,得到雏形的流程图;完成程序编程,满足前述功能,实现数据的输入和正确输出。
2.3.运行环境此法分析器的设计和运行环境:Microsoft Windows XP Professional /Microsoft Visual Studio 2005/Visual C++ 控制台应用程序。
2.4.程序的不足本程序只能分析小型的源程序,否则将会出现空间分配不足;能够分析的字符串的长度有限,否则,也会出现空间问题。
另外,变量反复使用,不利于阅读。
反复出现“fopen”被声明为否决的这样的警告信息。
程序冗长,未能充分利用C函数库的功能函数。
3.问题分析及相关原理介绍3.1. 编译程序介绍本词法分析器,预分析程序保存在文本文件sourcecode.txt中,该文件不能由执行程序自动创建,需要在程序执行前预先提供,程序拥有只读的权限。
程序逐个字符的分析源程序,能够识别标识符,整数,分界符,并分别把分析得到的字符写入相应文档:keyword,words,digit,single,double;其它字符标示为无法识别,记录在error文档中。
程序结束后,将最总结果写入文件Dualistic_formula,该文件的内容包括统计结果(排除重复出现的字符)和二元式。
这七个文件会在程序执行时自动创建,程序结束时,关闭文件,但保留文件的内容,以供查看和检验,测试。
不同类别的字符通过相应的函数模块来分析识别。
普通标识符由函数int word(char ch)来识别,并进一步由函数int keyword(char key[])来分离普通标识符和关键字;数字有函数i nt digit(char ch)来识别;分界符由函数int delimiter(char ch)来识别;其他字符即为非法字符。
该程序中,全局变量共有两个int characters_exist=0和int ountoffinal=0。
characters_exist用来判断是否是纯数字,countoffinal用来记录finalresult函数执行的次数。
统计主函数在内,总共16个函数模块,除了前面说到得识别字符的函数外,还有对文件进行操作的函数,对数组操作的函数和实现显示功能的函数。
主函数中有六个文件指针,十一个字符数组,十个实现不同功能的变量。
在程序设计过程中及时注释,方便复读和检测。
通过while循环和fgetc(FILE *fp)实现对字符的逐个读入。
3.2.各部分的功能介绍及分析各函数及功能说明int word( char ch) /*判断是否为字母*/int digit(char ch) /*判断是否为数字*/int delimiter(char ch) /*判断是否是分界符*/int keywordcompare(char key[],char keyword[]) /*比较关键字*/int keyword(char key[]) /*判断是否是关键字*/void writetofile(char cha[]) /*将数组cha[]写入文件Dualistic_formula*/ void keywordtofile(char cha[]) /*将关键字写入文件keyword*/void wordstofile(char cha[]) /*将标识符写入文件words*/void digittofile(char cha[]) /*将数字写入文件digit*/void singletofile(char cha[]) /*将单分界符写入文件single*/void doubletofile(char cha[]) /*将双分界符写入文件double*/void errortofile(char cha[]) /*将非法字符写入文件error*/void displayw(char ch,char cha[]) /*立即显示遇到的字符*//*显示统计信息并将二元式写入文件Dualistic_formula*/void finalresult(int df,char filen[],FILE *fpp,FILE *fpt)void cleararray(int n,char cha[]) /*清空数组*/3.3. 算法实现及模拟3.3.1总体流程图流程图1读入源文件有函数int fgetc(FILE *FILE)实现,文件是否结束及循环读入字符由while循环实现,while(!feof(fpr)),其中fpr=fopen("sourcecode.txt","r"),sourcecode.txt 为存放源程序的文本文件。