C语言词法分析程序java版
- 格式:pdf
- 大小:162.18 KB
- 文档页数:17
实验一词法分析程序设计与实现实验目的及内容调试并完成一个词法分析程序,加深对词法分析原理的理解。
二、实验原理(状态转换图)C语言子集关键字:begin if then while do end所有关键字都是小写。
运算符和界符::=+–*/<<=<>>>==;()#其他单词是标识符( ID)和整型常数( NUM),通过以下正规式定义:ID=letter ( letter| digit)*NUM=digit digit *空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。
各种单词符号对应的种别码单词符号种别码单词符号种别码begin 1 : 17if 2 := 18then 3 > 20while 4 <> 21do 5 <= 22end 6 < 23letter(letter| digit)* 10 >= 24digit digit * 11 = 25* 13 ; 26/ 14 ( 27+ 15 ) 28- 16 # 0词法分析程序的功能输入:所给文法的源程序字符串。
输出:二元组( syn,token 或 sum)构成的序列。
其中: syn 为单词种别码;token 为存放的单词自身字符串;sum 为整型常数。
软件平台及工具PC机以及 VISUAL C++软件。
实验方法、步骤(或:程序代码或操作过程)( 1)程序代码:#include<>#include<>#include<>char prog[80],token[8];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}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;ch=prog[p++];}token[m++]='\0';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')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;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=25;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;case'\n':syn=-2;break;default: syn=-1;break;}}void main(){p=0;row=1;cout<<"Please input string:"<<endl;do{(ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn)case 11: cout<<"("<<syn<<","<<sum<<")"<<endl; break;case -1: cout<<"Error in row "<<row<<"!"<<endl; break;case -2: row=row++;break;default: cout<<"("<<syn<<","<<token<<")"<<endl;break;}}while (syn!=0);}( 2)创建编辑程序( 3)连接、编译和调试程序( 4)运行程序五、实验过程原始记录( 测试数据、图表、计算等) (1)给定源程序begin x:=8; if x>0 then x:=2*x+1/5;end#输出结果(2)源程序(包括上式未有的while 、do 以及判断错误语句):beginx<=$;whilea<0dob<>9-x;end#。
Calcite(⼀):javacc语法框架及使⽤ 是⼀个动态数据管理框架。
它包含许多组成典型数据库管理系统的部分,但省略了存储原语。
它提供了⾏业标准的SQL解析器和验证器,具有可插⼊规则和成本函数的可⾃定义优化器,逻辑和物理代数运算符,从SQL到代数(以及相反)的各种转换。
以上是官⽅描述,⽤⼤⽩话描述就是,calcite实现了⼀套标准的sql解析功能,⽐如实现了标准hive sql的解析,可以避免繁杂且易出错的语法问题。
并暴露了相关的扩展接⼝供⽤户⾃定义使⽤。
其提供了逻辑计划修改功能,⽤户可以实现⾃⼰的优化。
(害,好像还是很绕!不管了)1. calcite的两⼤⽅向 从核⼼功能上讲,或者某种程度上讲,我们可以将calicite分为两⼤块,⼀块是对sql语法的解析,另⼀块是对语义的转化与实现; 为什么要将其分为⼏块呢?我们知道,基本上所有的分层,都是为了简化各层的逻辑。
如果我们将所有的逻辑全放在⼀个层上,必然存在⼤量的耦合,互相嵌套,很难实现专业的⼈做专业的事。
语法解析,本⾝是⼀件⽐较难的事情,但是因为有很多成熟的编译原理理论⽀持,所以,这⽅⾯有许多现成的实现可以利⽤,或者即使是⾃⼰单独实现这⼀块,也不会有太⼤⿇烦。
所以,这⼀层是⼀定要分出来的。
⽽对语义的转化与实现,则是⽤户更关注的⼀层,如果说前⾯的语法是标准规范的话,那么语义才是实现者最关⼼的东西。
规范是为了减轻使⽤者的使⽤难度,⽽其背后的逻辑则可能有天壤之别。
当有了前⾯的语法解析树之后,再来进⼀步处理语义的东西,必然⽅便了许多。
但也必定是个复杂的⼯作,因为上下⽂关联语义,并不好处理。
⽽我们本篇只关注语法解析这⼀块功能,⽽calcite使⽤javacc作为其语法解析器,所以我们⾃然主关注向javacc了。
与javacc类似的,还有antlr,这个留到我们后⾯再说。
calcite中,javacc应该属于⼀阶段的编译,⽽java中引⼊javacc编译后的样板代码,再执⾏⾃⼰的逻辑,可以算作是⼆阶段编译。
实验一编写词法分析程序1 实验类型设计型实验,4学时。
2 实验目的通过设计、调试词法分析程序,掌握词法分析程序的设计工具,即有穷自动机,进一步理解自动机理论;掌握文法转换成自动机的技术及有穷自动机实现的方法;会确定词法分析器的输出形式及标识符与关键字的区分方法;加深对课堂教学的理解,提高词法分析方法的实践能力。
3 背景知识词法分析作为相对独立的阶段来完成(对源程序或中间结果从头到尾扫描一次,并作相应的加工处理,生成新的中间结果或目标程序)。
在词法分析过程中,编译程序从外部介质中读取源程序文件中的各个字符,为正确地识别单词,有时还需进行超前搜索和回退字符等操作。
因此,为了提高读盘效率和便于扫描器进行工作,通常可采用缓冲输入的方案,即在内存中设置一个适当大小的输入缓冲区,将磁盘上的源程序字符串分批送入该缓冲区中,供扫描器进行处理。
词法分析程序的一般设计方案是:1、程序设计语言词法规则⇒正则文法⇒ FA;或:词法规则⇒正则表达式⇒ FA;2、NFA确定化⇒ DFA;3、DFA最小化;4、确定单词符号输出形式;5、化简后的DFA+单词符号输出形式⇒构造词法分析程序。
从设计方案可知,要构造词法分析程序,必须掌握以下三个知识点:文法、正则表达式和FA。
文法与语言的形式定义如下:一个形式文法G 是下述元素构成的一个元组(V N,V T,P,S )。
其中:1、V T—非空有限的终结符号集,即Σ;终结符:一个语言不可再分的基本符号。
2、V N—非空有限的非终结符号集;非终结符:也称语法变量,用来代表语法范畴。
一个非终结符代表一个一定的语法概念,是一个类(集合)记号,而不是一个体记号。
3、S —开始符号/识别符号,S∈V N;4、P —产生式规则集(或叫规则或生成式或重写规则);产生式:形如α → β或α ::= β的表达式,其中α为左部,β为右部。
α∈(V T∪V N)+且至少含一个V N;β∈(V T∪V N)*。
java.c转成java.class的编译过程Java是一种高级编程语言,它可以通过编译器将源代码(.java文件)转换成可执行的字节码文件(.class文件)。
这个过程被称为Java源代码的编译过程。
以下是Java源代码转换成Java字节码的编译过程的详细解释。
1. Java源代码的编写:在进行编译过程之前,首先需要编写Java源代码。
Java源代码是由Java编程语言写成的,可以使用任何文本编辑器来创建.java文件。
这些文件包含了程序的逻辑和功能实现。
2. 编译器的运行:一旦Java源代码被完成编写,接下来需要运行Java编译器(javac命令)来将源代码转换成可执行的字节码文件。
编译器会对源代码进行语法分析、词法分析和语义分析来检查代码是否符合Java语言的规范。
3. 语法和语义检查:编译器会对源代码进行语法和语义检查。
语法检查确保代码的结构和语法都是正确的,而语义检查则检查代码的语义是否符合Java语言的规范。
如果存在任何语法或语义错误,编译器将会给出错误提示,指出具体的问题。
4. 字节码生成:一旦代码通过了语法和语义检查,编译器将会生成相应的字节码文件。
字节码是一种中间形式的代码,它包含了源代码的逻辑和功能实现,并且可以在Java虚拟机(JVM)上执行。
5. 优化和转换:在生成字节码文件之后,编译器会对代码进行优化和转换。
优化可以提高代码的执行效率和性能,以及减少代码的体积。
转换则用于将某些高级语言特性转换成更低级的表示,以便于在Java虚拟机上执行。
6. 生成.class文件:最后,编译器将会生成可执行的字节码文件,也就是.class文件。
这个文件包含了源代码的所有信息,以及所需的库和依赖项。
.class文件可以被Java虚拟机加载和执行。
总结:Java源代码的编译过程包括了代码的编写、编译器的运行、语法和语义检查、字节码生成、优化和转换,以及生成最终的.class文件。
通过这个过程,我们可以将Java源代码转换成可执行的字节码文件,并在Java虚拟机上运行和执行。
利用VC++6.0编写C语言的词法分析昆明学院《编译原理课程设计》教学大纲(适用计算机科学与技术专业)(学分:1.0 学时:1周)一、教学目的和任务词法分析器要实现的功能是依次扫视字符串形式源程序中的各个字符,逐个识别出其中的单词。
从左至右扫描源程序的字符串,按照词法规则识别出一个个正确的单词,并转换成该单词相应的二元式交给语法分析使用。
该分析器可以识别关键字,普通标识符,阿拉伯数字,单分界符,代表双分界符。
通过本次词法分析器课程设计进一步理解高级语言在计算机中的执行过程,提高编程能力,培养好的程序设计风格。
同时通过某种可视化编程语言的应用,更进一步加深对编译原理中重点算法和编译技术的理解。
二、课程设计基本内容1、设计题目利用 VC++6.0 编写 C 语言的词法分析1、设计内容对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
2、设计要求利用该词法分析器完成对源程序字符串的词法分析。
输出形式是源程序的单词符号二元式的代码,并保存到文件中。
(1) 假设该语言中的单词符号及种别编码如下表所示。
单词符号及种别编码单词符号种别编码单词符号种别编码main 1 [ 28int 2 ] 29char 3 { 30if 4 } 31else 5 , 32for 6 : 33while 7 ;34标识符ID 10 >35整型常数NUM 20 <36= 21 >=37+ 22 <=38- 23 ==39* 24 !=40/ 25 & 41( 26 && 42) 27 || 43(2) 关键字main int char if else for while都是小写并都是保留字。
算符和界符 = + - * / & <<=>>===!= && || , : ; { } [ ] ( ) ID和NUM的正规定义式为:ID→letter(letter | didit)*NUM→dig it digit*letter→a | … | z | A | … | Zdigit→ 0 | … | 9如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码2.3 词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
其中初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};是图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。
简介:JavaCC是一个词法分析生成器和语法分析生成器。
词法分析和语法分析是处理输入字符序列的软件构件,编译器和解释器协同词法分析和语法分析来“解密”程序文件,不仅如此,词法分析和语法分析有更广泛的用途,我希望在本书列举的例子中能阐明这一点。
那么什么是词法分析器和语法分析呢?词法分析器可以将字符串解析为一个一个的标识符(Token),并且可以把这些标识符归类。
看一段C语言代码:C语言的词法分析器会把这段代码分解为如下的一些标识符:还会把这些标识符归类,在我们的例子中,这些标识符的类别为:其中EOF类别的标识符代表源文件的结束。
这些标识符出传送给语法分析器。
在C语言中,语法分析不需要所有的这些类别,在本例中SPACE类别的标识符不传送给语法分析器。
语法分析器会分析这些标识符,判断程序的结构。
在许多编译程序中,语法分析器用语法树来表示程序的结构。
编译器通过这棵树来产生代码。
看一个表达式:语法分析器基于语言规则分析这个表达式产生一棵树:如果输入没有语言的词法或语法,词法分析器或语法分析器都能产生错误信息。
JavaCC并不是一个词法分析器或者语法分析器,它只是一个生成器。
就是说,它读取文本后,基于一定的规则产生词法分析器和语法分析器的Java代码。
见图:进行词法分析和语法分析时必须要充分考虑各规则间的相互作用。
例如,在对 C语言的词法分析中,处理整型常量和浮点常量的代码是不能分开的,因为浮点数和整数的前面部分是一样的。
使用诸如JavaCC语法分析产生器,对整型常量和浮点常量是可以区分的,它们的共同点可在代码生成过程中提取出来。
这种模块性意味着JavaCC文件比直接的Java程序更容易写,更容易读,也更容易修改。
通过JavaCC 语法分析生成器的使用,软件工程师可以节省大量的时间,并且软件的质量也更高。
javaCC有三个工具:javaCC 用来处理语法文件(jj)生成解析代码;jjTree 用来处理jjt文件,生成树节点代码和jj文件,然后再通过javaCC生成解析代码;jjDoc 根据jj文件生成bnf范式文档(html)。
一、实验目的实验一:掌握开发Java应用程序的3个步骤:编写源文件、编译源文件和运行应用程序。
实验二:学习同时编译多个Java源文件。
实验三:掌握char型数据和int型数据之间的转换,了解Unicode字符表。
实验四:掌握数组属于引用型的一种复合型数据类型。
实验五:掌握Array类。
二、实验要求实验一:编写一个简单的Java应用程序,该程序在命令行窗口输出两行文字:“你好,欢迎学习Java”和“We are students”。
实验二:编写4个源文件:MainClass.java、A.java、B.java和C.java,每个源文件只有一个类。
其中,MainClass.java含有应用程序的主类,并使用A、B和C类。
将4个源文件保存到同一个目录下,然后编译MainClass.java文件。
实验三:编写一个Java应用程序,在命令行窗口输出希腊字母表。
实验四:编写一个Java应用程序,在命令行窗口输出数组的引用以及元素的值。
实验五:编写一个Java应用程序,输出数组a的全部元素,并将数组a的全部或部分元素复制到其他数组中,然后改变其他数组的元素的值,再输出数组a的全部元素。
三、实验详情实验一:一个简单的应用程序问题分析:在命令行窗口输出文字源代码(注释量不得少于代码量的1/3):public class Hello {public static void main (String args[ ]) {System.out.println("你好,欢迎学习Java");//命令行窗口输出“你好,欢迎学习Java”A a=new A( );a.fA( );}}class A {void fA( ) {System.out.println("We are students");//命令行窗口输出“We are students”}}运行结果:心得体会:在java里输出语句是System.out.println()实验二:联合编译问题分析:同时编译多个Java文件。
附录:核心代码清单C语言词法分析代码算法实习--------------------------------------------------------ByNLLWRQ功能类:packageconversion;
importjava.io.*;publicclassWork{publicStringfilename;publicintflage=1;publicinterror[]={0,0,0,0,0};publicinterror1[]={0,0,0,0,0,0};StringBufferbuffer=newStringBuffer();privateStringKeychar[]={"int","char","long","float","double","short","unsigned","struct","union","enum","auto","extern",
"static","register","typedef","void","if","else","switch","case","default","do","while","for","break","continue","return","goto","define","include","undef","ifdef","endif","line","sizeof","asm","fortran","ada","pascal"};privateStringKeyfile[]={"stdio","windows","stdlib","ctype","math","time","string"};publicWork(Stringfilename){this.filename=filename;}booleanisKeyfile(Stringch){for(inti=0;iif(Keyfile[i].equals(ch))returntrue;returnfalse;}booleanisKeychar(Stringch){for(inti=0;iif(Keychar[i].equals(ch))returntrue;returnfalse;}booleanisDigit(charch){if(ch>='0'&&ch<='9')returntrue;elsereturnfalse;}
booleanisLeter(charch){if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='_')returntrue;elsereturnfalse;}booleanisendline(charch){if(ch=='@')returntrue;elsereturnfalse;}publicvoidreadFile()throwsFileNotFoundException{try{FileReaderfr=newFileReader(this.filename);BufferedReaderbr=newBufferedReader(fr);Stringtemp=null;charend='@';while((temp=br.readLine())!=null){buffer.append(temp);buffer.append(end);}}catch(Exceptione){System.out.println("文件操作错误:"+e.toString());}
}publicStringAnalysis(){inti=0;charch;Stringstr1="";ViewFilea=null;while(ich=buffer.charAt(i);if(isLeter(ch)){StringBuffertemp=newStringBuffer();temp.append(ch);ch=buffer.charAt(++i);while(isLeter(ch)||isDigit(ch)){temp.append(ch);ch=buffer.charAt(++i);}if(isKeyfile(temp.toString())){ch=buffer.charAt(i++);if(ch!='.')error[2]++;else{temp.append(ch);ch=buffer.charAt(i++);if(ch!='h'){error[3]++;}elsetemp.append(ch);}str1+="("+temp+","+"“"+"line="+flage+"”"+")"+"\t是头文件"+"\n";}elseif(isKeychar(temp.toString()))str1+="("+temp+","+"“"+"line="+flage+"”"+")"+"\t是关键字"+"\n";elsestr1+="("+temp+","+"“"+"line="+flage+"”"+")"+"\t是标识符"+"\n";}elseif((ch=='[')||(ch==']')){str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\t是运算符"+"\n";i++;if(ch=='[')error[0]++;elseerror[1]++;}elseif(ch=='.'){str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\t是运算符"+"\n";i++;}elseif((ch=='{')||(ch=='}')){str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\n";i++;if(ch=='{')error1[0]++;elseerror1[1]++;}elseif((ch=='(')||(ch==')')){str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\n";i++;if(ch=='(')error1[2]++;
elseerror1[3]++;}elseif((ch==';')||(ch==',')||(ch=='"')){if(ch==','){str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\t是分隔符"+"\n";i++;}elseif(ch==';'){error1[4]++;str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\t是分隔符"+"\n";i++;}elseif(ch=='"'){error1[5]++;str1+="("+ch+","+"”"+"line="+flage+"“"+")"+"\n";i++;}}elseif(isDigit(ch)){StringBuffertemp=newStringBuffer();while(isDigit(ch)){temp.append(ch);ch=buffer.charAt(++i);}str1+="("+temp+","+"”"+"line="+flage+"”"+")"+"\t是数字"+"\n";}elseif(isendline(ch)){flage++;i++;}else{if((ch!='')){StringBuffertemp=newStringBuffer();if(ch=='+'){temp.append(ch);ch=buffer.charAt(++i);if(ch=='+'){temp.append(ch);i++;}if(ch=='='){temp.append(ch);i++;}}elseif(ch=='-'){temp.append(ch);ch=buffer.charAt(++i);if(ch=='-'){temp.append(ch);i++;}if(ch=='>'){temp.append(ch);i++;}if(ch=='='){temp.append(ch);i++;}}elseif(ch=='*'){temp.append(ch);ch=buffer.charAt(++i);if(ch=='*'){temp.append(ch);i++;}if(ch=='='){temp.append(ch);i++;}}elseif(ch=='/'){temp.append(ch);ch=buffer.charAt(++i);if(ch=='/'){temp.append(ch);i++;}if(ch=='='){temp.append(ch);i++;}}elseif(ch=='%'){temp.append(ch);