- 浏览: 191564 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (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 3603Java HotSpot(TM) Server VM warn ... -
Android rpg 游戏开发
2011-04-23 15:36 2432Android 游戏开发 记录点滴 rpg 游戏的地图 ... -
xpath的使用遇到的问题
2011-01-06 20:40 2927org.dom4j.InvalidXPathException ... -
Boolean的构造函数,你懂的
2010-11-27 20:52 1175学java不看源码是上不了一个等级的! ========== ... -
maven project 转化为eclipse project
2010-10-10 16:42 1462There is actually a very easy s ... -
UDAS
2010-09-24 12:31 1061UDAS 的全称:uniform data access s ... -
Java备忘
2010-05-02 09:12 1293/////////////////////////////// ... -
Java 虚拟机
2010-05-01 12:50 870//////////////////////////// ... -
cmm解释器--java实现
2010-04-18 13:02 1467目录: cmm编译器-cmm 语言词法分析-java实现 ... -
cmm编译器-cmm 语言LL1解释器构造-java实现
2010-04-18 12:57 2199附件是整个实验的文档和代码(由三人Hyvi,Heger,AJ负 ... -
cmm编译器-cmm 语言LL1语法分析-java实现
2010-04-18 12:11 2481cmm编译器-cmm 语言LL1语法分析-java实现 附件 ... -
cmm编译器-cmm 语言语法分析-javacc实现
2010-04-18 12:01 5363Cmm的文法: //程序开始 programàstmt-s ... -
Linux 下 Java环境的详细信息
2010-03-14 01:08 1241先把代码贴上: 1 import java.uti ... -
神奇的“按钮”
2010-03-11 23:12 823早期的反模式:神奇的按钮 神奇的Servlet ... -
RUBY
2009-06-10 14:23 952# rail:良好的惯例高于配 ... -
switch 与default 与break
2009-02-19 21:36 1078public class B { public s ... -
2008期末Collections&arrays总结
2009-01-16 00:48 846全部是静态方法 public static int binar ... -
2008年期末考试复习总结
2009-01-15 17:13 773类成员访问修饰符与继承的关系 私有的(private)类成员 ... -
Exercise 2
2008-11-26 17:12 1236Background This assignment ask ... -
SingleTon
2008-11-07 13:34 843大二期--中考试Java程序设计最后一题如下 Write do ...
相关推荐
CMM语言编译器的词法分析部分,含源码及软件。
这是我们大三的时候的一个编译器实践的课程设计,是将CMM语言(自行定义的一个C语言的子集)源程序进行词法分析、语法分析和最终编译运行,包括有源代码和相关文档,希望对初步学习编译器的同学有用,但不提倡直接拿...
JAVA的CMM编译器(词法+语法+语义+输出结果)
编译原理 解释器构造 cmm词法分析器 c#
包括词法分析,语法分析,中间代码(MSIL)生成。课程设计完成了,还是上传来和大家分享一下,开始自己在设计的时候想找C#代码的难啊,再者由于编译原理学得不好,所以本程序中用的方法,是针对CMM进行的,同时没有...
本人用java写的一个c语言的子集语言C--语言的解释器,与编辑器绑定在一起,大学编译原理课会学到的,有兴趣的话大家一起交流。
一个简单的编译器,具有词法,语法,语意全部功能
武汉大学cmm解释器构造实践课程作业,包含词法分析器 语法分析器 语义分析和界面。
本编译器所支持的词法和语法请参考第二第三小节 解压压缩包 运行命令 unzip compiler.zip 进入文件夹运行命令 ./compiler test.cmm 其中test.cmm可以替换成其他文件 如果报错,则输出错误行号输出语法树 产生语法树...
这是我在大三的时候解释器实践的课程设计,是用C#开发的,包括词法分析、语法分析和编译执行阶段,文档比较齐全,可供初步学习解释器的同学看看,但不鼓励直接拿来当作业用,起码也得自己看看源码,分析分析下,对...
C#版CMM解释器、编译器,包括词法分析语法分析
在学习CMM解释器构造课程是收集的资料 在各大网站上下载的CMM源码,自己整理 共六份代码,包括整个课程所需要的所有源码
实验1:词法和句法分析。 flex和bison来编译.l和.y文件。 Lab2:语义分析。 Lab3:中间代码生成。 在lab3/irsim提供了一个代码间解释器。 Lab4:机器代码生成。 生成的代码是spim兼容的。笔记可以通过以下方式安装...