- 浏览: 197965 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (124)
- java (25)
- 项目学习 (7)
- Web JSP (14)
- English study (1)
- windows (17)
- Thinking in Java (2)
- SSD4 VB (1)
- VB.NET (9)
- CSS (11)
- JQuery (4)
- Struts2 (0)
- spring (1)
- Hibernate (1)
- Dojo (0)
- Prototype (0)
- JSON (1)
- Ajax (1)
- my life my computer (1)
- html (1)
- JavaCC (0)
- c# (1)
- C/C++ (1)
- SQL (0)
- PS (1)
- Linux (21)
- Flex (1)
- mysql (1)
最新评论
-
wshy33:
按照这个“去掉/jre/lib/ext/目录下的jaxen.j ...
xpath的使用遇到的问题 -
白色蜻蜓:
什么是ssh
Linux ---SSH密钥问题解决 -
lucane:
今天请教R大一个问题,然后用他提到的hsdis跑代码看,但是我 ...
JVM 反汇编动态运行代码 -
igotti:
原来-XX:+PrintAssembly还需要安装插件
JVM 反汇编动态运行代码 -
RednaxelaFX:
嗯Good,继续有新的同好开始鼓捣这些东西真好 ^_^我在编译 ...
JVM 反汇编动态运行代码
词法设计理念
1. 注释处理: 在处理注释的问题上,我采用了正则表达式处理,在词法分析程序执行前,先讲注释匹配掉,将其换成一个空格。在处理空格上,为了避免对空格多重过滤,依然使用正则表达式将2个或者两个以上的空格匹配成一个空格。这样后在词法分析过程中,逻辑的处理变得更简单。
对注释的处理方法:
public static String omitComment(String str)
2. 词法分析的原理:依然使用的是每次获取一个字符,分析它是字母、数字、操作符、分隔符等以及之前设置状态。这样就可确定碰到这个字符后是什么状态。一共设置了3种状态。
3. 程序的结构说明:
l 程序一开始需要实例一个名为LexicalAnalysis类的对象。这个对象的 构造函数有两个
1. LexicalAnalysis(String sourcefilename)这个构造函数的参数为cmm源码的路径,这样在实例化这个类时就已经将源码加载在实例中。
2. LexicalAnalysis(String sourcefilename, String[] reservedwords)
第二个构造函数较第一个函数多了一个数组的参数,从字面上可以知道,这个参数为关键字的数组,这样以来,用户可以自定义自己关键字。然后构造属于自定义的词法分析程序。同时,如果用户没想自定义关键字就可以使用第一个构造函数并使用了默认的关键字。
在实例化词法分析对象时使用了工具类,对要分析的cmm源文件进行读取。读取后将其存在字符串中,便于后面的词法分析。
l 在实例化词法分析对象后,就可以调用分析方法parse() ,
l 在分析过程中,设置一个全局的变量
StringBuilder resultStringBuilder = new StringBuilder();
将其用来保存词法分析的结果。并将其输出。
4.错误的处理:
w 词法分析对数值的错误处理:数值不能以.结尾。
if (charArray[index - 1] == '.') {
resultStringBuilder.append(s + ":数值不能以\".\"结尾。\n");
w 词法分析对字符串的处理:标识符不能以下划线结尾。
if (charArray[index - 1] == '_') {
resultStringBuilder.append(s + ":标识符不能以\"_\"结尾。\n");
5.测试
测试数据
int i; i=1; /** *Author:Hyvi * *lexical Analysis */ if(i==1){ write i; }else{ i=0; }
输出的结果如下
int:保留字。
t:标识符。
i:标识符。
;:分隔符。
i:标识符。
=:操作符。
1:整数。
;:分隔符。
if:保留字。
(:分隔符。
i:标识符。
==:操作符。
1:整数。
):分隔符。
{:分隔符。
write:保留字。
i:标识符。
;:分隔符。
}:分隔符。
else:保留字。
{:分隔符。
i:标识符。
=:操作符。
0:整数。
;:分隔符。
}:分隔符。
======================================
问题列表:
问题1
如上cmm源码在第一次运行时出项如下错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at exercise.LexicalAnalysis.parse(LexicalAnalysis.java:66)
at exercise.LexicalAnalysis.main(LexicalAnalysis.java:188)
解决方法:
根据提示问题错在:ch = charArray[index]; 字符串尾部的空格引起的。
修改前:
ch = charArray[index];
修改后
while (ch == ' ') { sourcetemp1 = sourcetemp1.substring(1); charArray = sourcetemp1.toCharArray(); if(sourcetemp1.length()!=0)ch = charArray[index]; else { flag =true ; state =4; break; } } if(flag){ break; }
这样后在遇到文件结尾时,就跳switch以及while循环。
分析及评价:
词法分析采用有穷机的机制。根据不同的状态及读取的字符决定有穷机的走向。在本次试验中,对于注释的处理是采用了java中正则表达式方法处理,这是一个独到的处理。试验中使用java中对字符串的处理以及数组的操作来完成词法分析。当然一个程序不可能达到完美,总存在着不足的地方。这个词法分析程序也不例外。在对注释的处理里,依然存在这个不足,使用java中的正则表达式的处理的效率可能不及对字符的处理。
词法分析主类:
工具类:package exercise;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import exercise;
public class LexicalAnalysis {
private String[] reservedwords;
private String source;
private String result;
private static Character[] operators = new Character[] { '+', '-', '*',
'/', '=', '<', '<', '>' };
private static Character[] seperators = new Character[] { '(', ')', ';',
'{', '}', '[', ']' };
LexicalAnalysis(String sourcefilename) {
try {
this.source = BufferedInputFile.read(sourcefilename);
} catch (IOException e) {
this.source = "filenotexist";
// 在console里输出
System.err.println("读取代码文件失败,可能文件路径出错了");
}
this.reservedwords = new String[] { "if", "while", "else", "read",
"write", "int", "real" };
}
public LexicalAnalysis(String sourcefilename, String[] reservedwords) {
try {
this.source = BufferedInputFile.read(sourcefilename);
} catch (IOException e) {
this.source = "filenotexist";
// 在console里输出
System.err.println("读取代码文件失败,可能文件路径出错了");
}
this.reservedwords = reservedwords;
}
// once parse_begind
public String parse() {
if (this.source.equals("filenotexist")) {
return (this.result = this.source);
}
// drop comment and spaces
String sourcetemp1 = omitComment(this.source);
// string to charArray
char[] charArray = (sourcetemp1.trim()).toCharArray();
//System.out.println(sourcetemp1);
int state = 0;
int index = 0;
StringBuilder resultStringBuilder = new StringBuilder();
while (index <= charArray.length) {
switch (state) {
// 开始状态
case 0: {
index = 0;
boolean flag =false;
char ch = charArray[index];
//System.out.println(ch);
while (ch == ' ') {
sourcetemp1 = sourcetemp1.substring(1);
charArray = sourcetemp1.toCharArray();
if(sourcetemp1.length()!=0)ch = charArray[index];
else {
flag =true ;
state =4;
break;
}
}
if(flag){
break;
}
if (Character.isLetter(ch) || '_' == ch) {
state = 1;
} else if (Character.isDigit(ch)) {
state = 2;
} else if (contain(operators, (Character) ch)) {
state = 3;
} else if (contain(seperators, (Character) ch)) {
String s = charArrayToString(charArray, index+1);
resultStringBuilder.append(s + ":分隔符。\n");
sourcetemp1 = sourcetemp1.substring(index + 1);
charArray = sourcetemp1.toCharArray();
state = 0;
} else {
resultStringBuilder.append("error");
sourcetemp1 = sourcetemp1.substring(index + 1);
charArray = sourcetemp1.toCharArray();
state = 0;
}
break;
}
case 1: {
char ch = charArray[index];
if (Character.isLetter(ch) || '_' == ch
|| Character.isDigit(ch)) {
} else {
String s = charArrayToString(charArray, index);
if (contain(reservedwords, s)) {
resultStringBuilder.append(s + ":保留字。\n");
} else if (charArray[index - 1] == '_') {
resultStringBuilder.append(s + ":标识符不能以\"_\"结尾。\n");
} else {
resultStringBuilder.append(s + ":标识符。\n");
}
sourcetemp1 = sourcetemp1.substring(index);
charArray = sourcetemp1.toCharArray();
state = 0;
}
break;
}
case 2: {
char ch = charArray[index];
if (Character.isDigit(ch))
state = 2;
else if (ch == '.')
state = 2;
else {
String s = charArrayToString(charArray, index);
if (charArray[index - 1] == '.') {
resultStringBuilder.append(s + ":数值不能以\".\"结尾。\n");
}else if(s.contains(".")){
resultStringBuilder.append(s + ":实数。\n");
}
else {
resultStringBuilder.append(s + ":整数。\n");
}
sourcetemp1 = sourcetemp1.substring(index);
charArray = sourcetemp1.toCharArray();
state = 0;
}
break;
}
case 3: {
char ch = charArray[index];
if (ch == '>' || ch == '=') {
state = 3;
} else {
String s = charArrayToString(charArray, index);
resultStringBuilder.append(s + ":操作符。\n");
sourcetemp1 = sourcetemp1.substring(index);
charArray = sourcetemp1.toCharArray();
state = 0;
}
break;
}
default: {
resultStringBuilder.append("");
break;
}
}
index++;
}
if (resultStringBuilder.toString().contains("error"))
resultStringBuilder = new StringBuilder("error");
return this.result = resultStringBuilder.toString();
}
public static String charArrayToString(char[] array, int index) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < index; i++) {
sb.append(array[i]);
}
return sb.toString();
}
public static String omitComment(String str) {
String result = "";
Pattern pattern = Pattern
.compile("(/\\u002A(.*?)(\n(.*?))*\\u002A/|//.*\\n)");
Matcher matcher = pattern.matcher(str);
String temp = matcher.replaceAll(" ");
result = (pattern.compile("(\\n|\\t|\\r| |\f)+")).matcher(temp)
.replaceAll(" ");
return result;
}
public static <T> boolean contain(T[] array, T t) {
boolean flag = false;
for (T a : array) {
if (a.equals(t))
flag = true;
}
return flag;
}
public static void main(String[] args) {
LexicalAnalysis s = new LexicalAnalysis("C:/1.txt");
System.out.println(s.parse());
}
public String[] getReservedwords() {
return reservedwords;
}
public String getSource() {
return source;
}
public String getResult() {
return result;
}
public void setReservedwords(String[] reservedwords) {
this.reservedwords = reservedwords;
}
public void setSource(String source) {
this.source = source;
}
public void setResult(String result) {
this.result = result;
}
}
package exercise; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class BufferedInputFile { public static String read(String filename) throws IOException{ BufferedReader bufferedReader =new BufferedReader(new FileReader(filename)); StringBuilder builder =new StringBuilder(); String str; while((str=bufferedReader.readLine())!=null){ builder.append(str+"\n"); } bufferedReader.close(); return builder.toString(); } }
发表评论
-
JVM 反汇编动态运行代码
2011-05-11 21:15 3692Java HotSpot(TM) Server VM warn ... -
Android rpg 游戏开发
2011-04-23 15:36 2491Android 游戏开发 记录点滴 rpg 游戏的地图 ... -
xpath的使用遇到的问题
2011-01-06 20:40 3021org.dom4j.InvalidXPathException ... -
Boolean的构造函数,你懂的
2010-11-27 20:52 1251学java不看源码是上不了一个等级的! ========== ... -
maven project 转化为eclipse project
2010-10-10 16:42 1516There is actually a very easy s ... -
UDAS
2010-09-24 12:31 1113UDAS 的全称:uniform data access s ... -
Java备忘
2010-05-02 09:12 1364/////////////////////////////// ... -
Java 虚拟机
2010-05-01 12:50 908//////////////////////////// ... -
cmm解释器--java实现
2010-04-18 13:02 1535目录: cmm编译器-cmm 语言词法分析-java实现 ... -
cmm编译器-cmm 语言LL1解释器构造-java实现
2010-04-18 12:57 2270附件是整个实验的文档和代码(由三人Hyvi,Heger,AJ负 ... -
cmm编译器-cmm 语言LL1语法分析-java实现
2010-04-18 12:11 2563cmm编译器-cmm 语言LL1语法分析-java实现 附件 ... -
cmm编译器-cmm 语言语法分析-javacc实现
2010-04-18 12:01 5508Cmm的文法: //程序开始 programàstmt-s ... -
Linux 下 Java环境的详细信息
2010-03-14 01:08 1284先把代码贴上: 1 import java.uti ... -
神奇的“按钮”
2010-03-11 23:12 890早期的反模式:神奇的按钮 神奇的Servlet ... -
RUBY
2009-06-10 14:23 989# rail:良好的惯例高于配 ... -
switch 与default 与break
2009-02-19 21:36 1128public class B { public s ... -
2008期末Collections&arrays总结
2009-01-16 00:48 889全部是静态方法 public static int binar ... -
2008年期末考试复习总结
2009-01-15 17:13 843类成员访问修饰符与继承的关系 私有的(private)类成员 ... -
Exercise 2
2008-11-26 17:12 1268Background This assignment ask ... -
SingleTon
2008-11-07 13:34 883大二期--中考试Java程序设计最后一题如下 Write do ...
相关推荐
本项目聚焦于词法分析阶段,使用Java语言实现了一个针对CMM(假设是一种自定义的编程语言)的词法分析器。 词法分析,也称为扫描或标记,是编译器或解释器的第一个阶段。它的任务是将源代码分解成一系列的有意义的...
本文将深入探讨如何使用Java语言来实现一个CMM词法分析器。 词法分析器,也称为扫描器或词法器,其主要任务是将源代码文本转换为一系列有意义的标记(tokens),这些标记是语言的基本构建块,如关键字、标识符、...
下面我们将深入探讨CMM词法分析的原理、Java实现的关键技术和相关知识点。 1. **词法分析定义与作用** 词法分析,又称扫描或词法生成,是编译器前端的第一步。它的主要任务是识别源代码中的关键字、标识符、常量、...
"CMM_cmm词法分析器"指的是该压缩包内包含CMM语言的词法分析器源码,这可能是用Java编程语言实现的。Java是一种广泛使用的面向对象的编程语言,具有跨平台的特性,因此适合开发这样的工具。 描述中提到的"CMM语言...
本压缩包"**cmm.rar**"包含了关于CMM编译器的详细资料,特别是针对Java语言的实现。以下是基于提供的文件信息解析出的相关知识点: 1. **CMM Java**: CMM可以应用于Java语言,创建一个用于处理Java源代码的编译器。...
而"**CMM词法分析器**"可能是一个实现了这个功能的Java程序,这表明开发者选择Java作为实现词法分析器的编程语言,Java以其跨平台性和丰富的库支持而受到青睐。 词法分析是编译器构造的重要组成部分,它对程序的...
"**cmm语法 词法语法 语法_词法**"这些标签进一步强调了Cmm编译器对语言规范的重视,特别是关于如何定义和解析语言的结构。 最后,压缩包内的"Cmm"文件可能是编译器的源代码,包含了实现上述功能的函数和数据结构。...
CMM编译器包含的主要部分有前端分析、中间代码生成、优化以及后端代码生成等关键组件。 1. **前端分析**:这一阶段主要包括词法分析、语法分析和语义分析。词法分析将源代码分解成一个个有意义的符号(token),...
CMM词法分析器是基于Java编程语言实现的一个解析工具,主要用于处理CMM(可能是某种特定的编程语言或标记语言)的源代码。词法分析是编译器设计中的一个关键阶段,它将源代码分解成一系列有意义的、独立的单元,称为...
在这个特定的案例中,"cmm词法分析器作业"是一个关于构建词法分析器的项目,使用了ANTLR工具,并以Java语言作为开发语言。ANTLR是一个强大的解析器生成器,广泛应用于语法解析任务,如编程语言、配置文件等的解析。 ...
本篇将深入探讨CMM词法分析器以及如何使用C#来实现这一功能。 首先,词法分析(也称为扫描或Tokenization)是编译器或解释器的第一个阶段。它的任务是将源代码分解成一系列有意义的、独立的元素,称为词法单元或...
在CMM语言的编译器中,这个词法分析器可能就是用lex或flex编写,或者完全用C语言手工实现的。 在构建词法分析器时,开发者需要定义每个标记的模式,并指定当遇到这些模式时应如何处理。一旦词法分析器完成,它将为...
总结来说,"基于ANTLR4的CMM语言编译器"项目展示了如何使用ANTLR4工具来设计和实现一个编译器,包括文法定义、词法分析、语法分析、语义分析和代码生成等关键步骤。对于学习编译原理和实践编译器开发的人员来说,这...
总的来说,通过实现CMM解释器,我们可以深入了解编译器和解释器的工作流程,掌握词法分析、语法分析和语义分析的关键技术,同时提升Java编程能力。这是一个极好的实践项目,适合对编译原理感兴趣的初学者和开发者...
【标题】: "基于Java实现的CMM语言解释器,包括词法分析,语法分析等" 这个项目涉及到了计算机编程中的一个重要领域——编译原理,具体是关于如何使用Java语言来构建一个CMM语言的解释器。CMM可能是一种自定义的...
**CMM词法分析器**:词法分析器,又称扫描器,是编译器的第一步。它将源代码分解成一个个独立的、有意义的符号,称为“词法单元”或“token”。这些词法单元可能是关键字、标识符、常量、运算符等。词法分析器通过...
在“解释器作业2”这个文件中,很可能是对CMM语言词法分析的实现或测试案例。可能包含了各种源代码片段,以及预期的标记序列。通过运行词法分析器,可以检查它是否能正确地将源代码转换为标记流。这通常涉及到正则...
这是我们大三的时候的一个编译器实践的课程设计,是将CMM语言(自行定义的一个C语言的子集)源程序进行词法分析、语法分析和最终编译运行,包括有源代码和相关文档,希望对初步学习编译器的同学有用,但不提倡直接拿...
本文将深入探讨“CMM_词法分析和语法分析_java编写”这一主题,结合Java语言来实现对CMM语言的解析。 首先,我们需要理解词法分析和语法分析的基本概念。词法分析,也称为扫描或分词,是编译器或解释器的第一个阶段...