正文
java词法分析源代码 java词法分析简单代码
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
什么是Java代码的编译与反编译?
Java代码的编译与反编译
2017-02-21Hollis数盟
一、什么是编译
1、利用编译程序从源语言编写的源程序产生目标程序的过程。
2、用编译程序产生目标程序的动作。编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成;代码优化;目标代码生成。主要是进行词法分析和语法分析,又称为源程序分析,分析过程中发现有语法错误,给出提示信息。
二、什么是反编译
计算机软件反向工程(Reverseengineering)也称为计算机软件还原工程,是指通过对他人软件的目标程序(可执行程序)进行“逆向分析、研究”工作,以推导出他人的软件产品所使用的思路、原理、结构、算法、处理过程、运行方法等设计要素,某些特定情况下可能推导出源代码。反编译作为自己开发软件时的参考,或者直接用于自己的软件产品中。
三、Java类的编译与反编译
我们在最初学习Java的时候,会接触到两个命令:javac和java,那个时候我们就知道,javac是用来编译Java类的,就是将我们写好的helloworld.java文件编译成helloworld.class文件。
class文件打破了C或者C++等语言所遵循的传统,使用这些传统语言写的程序通常首先被编译,然后被连接成单独的、专门支持特定硬件平台和操作系统的二进制文件。通常情况下,一个平台上的二进制可执行文件不能在其他平台上工作。而Javaclass文件是可以运行在任何支持Java虚拟机的硬件平台和操作系统上的二进制文件。
那么反编译呢,就是通过helloworld.class文件得到java文件(或者说是程序员能看懂的Java文件)
四、什么时候会用到反编译
1、我们只有一个类的class文件,但是我们又看不懂Java的class文件,那么我们可以把它反编译成我们可以看得懂的文件。
2、学习Java过程中,JDK的每个版本都会加入越来越多的语法糖,有些时候我们想知道Java一些实现细节,我们可以借助反编译。
五、反编译工具
1、javap
2、Jad:官网(墙裂推荐)
客户端:
可以在官网下载可执行文件,找到对应的操作系统的对应版本,然后进行安装使用。
因为我使用的是linux操作系统,所以我下载的是Linux版本的工具,这个工具下载好之后会有一个执行文件,只要在执行文件所在目录执行./jadhelloworld.class就会在当前目录下生成helloworld.jad文件,该文件里就是我们很熟悉的Java代码
Eclipse插件:
下载地址在官网下载插件的jar包,然后将jar包放到eclipse的plugins目录下‘在打开Eclipse,Eclipse-Window-Preferences-Java,此时你会发现会比原来多了一个JadClipse的选项,单击,在Pathtodecompiler中输入你刚才放置jad.exe的位置,也可以制定临时文件的目录。当然在JadClipse下还有一些子选项,如Debug,Directives等,按照默认配置即可。基本配置完毕后,我们可以查看一下class文件的默认打开方式,Eclipse-Window-Preferences-General-Editors-FileAssociations我们可以看到class文件的打开方式有两个,JadClipse和Eclipse自带的ClassFileViewer,而JadClipse是默认的。全部配置完成,下面我们可以查看源码了,选择需要查看的类,按F3即可查看源码
如何用JAVA编写词法分析器程序
我也做过这个作业
package source;
import java.util.LinkedList;
public class LexicalAnalysis
{
//私有变量声明
private LinkedListWord optr = new LinkedListWord();
private String exp;
//词法分析
public LinkedListWord lexical_analysis(String exp)
{
char ch = '\0'; //当前文件指针内容
int index = 0; //文件指针
StringBuffer strToken = new StringBuffer("");
//扫描处理字符串
while(true)
{
ch = exp.charAt(index);
index++;
//标识符(字母开头,数字或字符组成)
if(Character.isLetter(ch))
{
while(Character.isLetter(ch) || Character.isDigit(ch))
{
strToken.append(ch);
ch = exp.charAt(index);
index++;
}
index--;
String str = strToken.toString();
if(str.equals("if"))
optr.add(new Word(str, 13));
else if(str.equals("else"))
optr.add(new Word(str, 14));
else if(str.equals("then"))
optr.add(new Word(str, 15));
else
optr.add(new Word(str, 26));
}
//数字
else if(Character.isDigit(ch))
{
while(Character.isDigit(ch))
{
strToken.append(ch);
ch = exp.charAt(index);
index++;
}
index--;
optr.add(new Word(strToken.toString(), 26));
}
//加号或自加
else if(ch == '+')
{
ch = exp.charAt(index);
index++;
if(ch == '+')
optr.add(new Word("++", 21));
else if(ch == '=')
optr.add(new Word("+=", 16));
else
{
index--;
optr.add(new Word("+", 19));
}
}
//加号或自加
else if(ch == '-')
{
ch = exp.charAt(index);
index++;
if(ch == '-')
optr.add(new Word("--", 21));
else if(ch == '=')
optr.add(new Word("-=", 16));
else
{
index--;
optr.add(new Word("-", 19));
}
}
//乘法或乘幂
else if(ch == '*')
{
ch = exp.charAt(index);
index++;
if(ch == '*')
optr.add(new Word("**", 20));
else if(ch == '=')
optr.add(new Word("*=", 16));
else
{
index--;
optr.add(new Word("*", 20));
}
}
//除法或注释
else if(ch == '/')
{
ch = exp.charAt(index);
index++;
//多行注释
if(ch == '*')
{
while(true)
{
ch = exp.charAt(index);
index++;
if(ch == '*')
{
ch = exp.charAt(index);
index++;
if(ch == '/') break;
else if(ch == '\n')
{
exp = Input.newLine();
index = 0;
ch = exp.charAt(index);
index++;
}
else index--;
}
else if(ch == '#')
{
int tIndex = index - 1;
if(exp.length() tIndex+9)
{
String end = exp.substring(tIndex, tIndex+9);
if(end.equals("#?e_N_d?#")) break;
}
else
{
System.out.println("非法符号\'#\'后的语句忽略!");
exp = Input.newLine();
index = 0;
break;
}
}
else if(ch == '\n')
{
exp = Input.newLine();
index = 0;
}
}
}
//单行注释
else if(ch == '/')
break;
else if(ch == '=')
optr.add(new Word("/=", 16));
else
{
index--;
optr.add(new Word("/", 20));
}
}
//大于或大于等于或右移
else if(ch == '')
{
ch = exp.charAt(index);
index++;
if(ch == '=')
optr.add(new Word("=", 18));
else if(ch == '')
optr.add(new Word("", 20));
else
{
index--;
optr.add(new Word("", 18));
}
}
//小于或小于等于或左移
else if(ch == '')
{
ch = exp.charAt(index);
index++;
if(ch == '=')
optr.add(new Word("=", 18));
else if(ch == '')
optr.add(new Word("", 20));
else
{
index--;
optr.add(new Word("", 18));
}
}
//赋值或等于
else if(ch == '=')
{
ch = exp.charAt(index);
index++;
if(ch == '=')
optr.add(new Word("==", 18));
else
{
index--;
optr.add(new Word("=", 16));
}
}
//或运算按位或
else if(ch == '|')
{
ch = exp.charAt(index);
index++;
if(ch == '|')
optr.add(new Word("||", 17));
else
{
index--;
optr.add(new Word("|", 20));
}
}
//与运算
else if(ch == '')
{
ch = exp.charAt(index);
index++;
if(ch == '')
optr.add(new Word("", 17));
else
{
index--;
optr.add(new Word("", 20));
}
}
//非运算或不等于
else if(ch == '!')
{
ch = exp.charAt(index);
index++;
if(ch == '=')
optr.add(new Word("!=", 18));
else
{
index--;
optr.add(new Word("!", 21));
}
}
//按位亦或
else if(ch == '^')
optr.add(new Word("^", 20));
//取模运算
else if(ch == '%')
optr.add(new Word("%", 20));
//左括号
else if(ch == '(')
optr.add(new Word("(", 22));
//右括号
else if(ch == ')')
optr.add(new Word(")", 23));
//左大括号
else if(ch == '{')
optr.add(new Word("{", 24));
//右大括号
else if(ch == '}')
optr.add(new Word("}", 25));
//结束扫描标志为:#?e_N_d?#
else if(ch == '\n')
{
break;
}
else if(ch == '#')
{
int tIndex = index - 1;
if(exp.length() tIndex+9)
{
String end = exp.substring(tIndex, tIndex+9);
if(end.equals("#?e_N_d?#"))
{
optr.add(new Word("#", 27));
break;
}
}
else
{
System.out.println("非法符号\'#\'后的语句忽略!");
optr.add(new Word("#", 27));
break;
}
}
//清空扫描串
strToken.setLength(0);
}
return optr;
}
}
我要做个JAVA词法分析工具,求JAVA的所有关键字和操作符
我有Java API里面有所有的接口和类,以及类里的方法
赋值操作符:
= 赋值符号。
+= 加等赋值。
-= 减等赋值。
*= 乘等赋值。
/= 除等赋值。
运算操作符:
+ 加运算符
- 减运算符
* 乘运算符
/ 除运算符
% 求余运算符
++ 自增1运算符
-- 自减1运算符
关系操作符:
小于。
= 小于或者等于。
大于。
= 大于或者等于。
== 等于。
!= 不等于(大于或小于)。
逻辑操作符:
?: if-then-else
逻辑与。位操作符。将左右表达式按二进制按位进行与操作(同位均为1则该位为1,否则为0)。
与操作。
| 逻辑或。
|| 或操作。
^ XOR。
== 等于
!= 不等于
! 逻辑非操作。
】
Abstract 抽象的
一个Java语言中的关键字,用在类的声明中来指明一个类是不能被实例化的,但是可以被其它类继承。一个抽象类可以使用抽象方法,抽象方法不需要实现,但是需要在子类中被实现
break
一个Java的关键字,用来改变程序执行流程,立刻从当前语句的下一句开始执行从。如果后面跟有一个标签,则从标签对应的地方开始执行
case
Java语言的关键字,用来定义一组分支选择,如果某个值和switch中给出的值一样,就会从该分支开始执行。
catch
Java的一个关键字,用来声明当try语句块中发生运行时错误或非运行时异常时运行的一个块。
char
Java语言的一个关键字,用来定义一个字符类型
continue
一个Java的关键字,用来打断当前循环过程,从当前循环的最后重新开始执行,如果后面跟有一个标签,则从标签对应的地方开始执行。
do
一个Java语言的关键字,用来声明一个循环,这个循环的结束条件可以通过while关键字设置
double
一个Java语言的关键字,用来定义一个double类型的变量
else
一个Java语言的关键字,如果if语句的条件不满足就会执行该语句。
final
一个Java语言的关键字。你只能定义一个实体一次,以后不能改变它或继承它。更严格的讲:一个final修饰的类不能被子类化,一个final修饰的方法不能被重写,一个final修饰的变量不能改变其初始值。
finally
一个Java语言的关键字,用来执行一段代码不管在前面定义的try语句中是否有异常或运行时错误发生。
float
一个Java语言的关键字,用来定义一个浮点数变量
for
一个Java语言的关键字,用来声明一个循环。程序员可以指定要循环的语句,推出条件和初始化变量。
if
Java编程语言的一个关键字,用来生成一个条件测试,如果条件为真,就执行if下的语句。
implements
Java(TM)编程语言的一个关键字,在类的声明中是可选的,用来指明当前类实现的接口。
import
Java(TM)编程语言的一个关键字,在源文件的开始部分指明后面将要引用的一个类或整个包,这样就不必在使用的时候加上包的名字。
instanceof
一个二操作数的Java(TM)语言关键字,用来测试第一个参数的运行时类型是否和第二个参数兼容。
int
Java(TM)的一个关键字,用来定义一个整形变量
Java(TM)的一个关键字,用来定义一系列的方法和常量。它可以被类实现,通过implements关键字。
long
Java语言的一个关键字,用来定义一个long类型的变量。
private
Java语言的一个关键字,用在方法或变量的声中。它表示这个方法或变量只能被这个类的其它元素所访问。
protected
Java语言的一个关键字,在方法和变量的声明中使用,它表示这个方法或变量只能被同一个类中的,子类中的或者同一个包中的类中的元素所访问。
public
Java语言的一个关键字,在方法和变量的声明中使用,它表示这个方法或变量能够被其它类中的元素访问。
return
Java语言的一个关键字,用来结束一个方法的执行。它后面可以跟一个方法声明中要求的值。
short
Java语言的关键字,用来定义一个short类型的变量。
static
Java语言的关键字,用来定义一个变量为类变量。类只维护一个类变量的拷贝,不管该类当前有多少个实例。"static" 同样能够用来定义一个方法为类方法。类方法通过类名调用而不是特定的实例,并且只能操作类变量。
this
Java语言的关键字,用来代表它出现的类的一个实例。this可以用来访问类变量和类方法。
throw
Java语言的关键字,允许用户抛出一个exception对象或者任何实现throwable的对象
throws
Java语言的关键字,用在方法的声明中来说明哪些异常这个方法是不处理的,而是提交到程序的更高一层。
transient
Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
try
Java语言的关键字,用来定义一个可能抛出异常语句块。如果一个异常被抛出,一个可选的catch语句块会处理try语句块中抛出的异常。同时,一个finally语句块会被执行,无论一个异常是否被抛出。
void
Java语言的关键字,用在Java语言的方法声明中说明这个方法没有任何返回值。"void"也可以用来表示一句没有任何功能的语句。
volatile
Java语言的关键字,用在变量的声明中表示这个变量是被同时运行的几个线程异步修改的。
while
Java语言的一个关键字,用来定义一段反复执行的循环语句。循环的退出条件是while语句的一部分。
关于break和continue。
continue语句与break语句相关,但较少用到。continue语句用于使其所在的for、while或do-while语句开始下一次循环。在while与do-while语句中,continue语句的执行意味着立即执行测试部分;在for循环语句中,continue语句的执行则意味着使控制传递到增量部分。
Java没有关键字default,如果class定义前什么也不写就是默认型,说明访问他的范围是包内
请用JAVA编程输入一个语句进行词法分析
我最近正在学编译原理,我有c语言实现的词法分析程序,不知可不可以,识别的是TEST语言的单词。
#includestdio.h
#includectype.h
#includestring.h
#define keywordSum 8
char * keyword[keywordSum] = {"do", "else", "for", "if", "int", "read", "while", "write"};
char singleword[50] = "+-*(){};,:";
char doubleword[10] = "=!|";
char Scanin[300], Scanout[300];
FILE * fin, * fout;
int binaryFind(int low, int high, char * c1, char ** c2) {
int mid;
if(low high) return -1;
mid = (low+high)/2;
if(strcmp(c1, c2[mid]) == 0) return mid;
else if(strcmp(c1, c2[mid]) 0) return binaryFind(mid+1, high, c1, c2);
else return binaryFind(low, mid-1, c1, c2);
}
int TESTscan() {
char ch, token[40];
int es = 0, j, n;
printf("请输入源文件名(包括路径):");
scanf("%s", Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s", Scanout);
if((fin=fopen(Scanin, "r")) == NULL) {
printf("\n打开词法分析输入文件出错!\n");
return 1;
}
if((fout=fopen(Scanout, "w")) == NULL) {
printf("\n创建词法分析输出文件出错!\n");
return 2;
}
// printf("%c", getc(fin));
ch = getc(fin);
while(ch != EOF) {
while(ch==' ' || ch=='\n' || ch=='\t') {
ch = getc(fin);
}
if(isalpha(ch)) { //标识符
token[0] = ch;
j = 1;
ch = getc(fin);
while(isalnum(ch)) { //判断当前字符是否是字母或数字
token[j++] = ch;
ch = getc(fin);
}
token[j] = '\0';
// printf("%s", token);
n = binaryFind(0, keywordSum-1, token, keyword);
if(n 0 ) {
fprintf(fout, "%s\t%s\n", "ID", token);
} else {
fprintf(fout, "%s\t%s\n", token, token);
}
} else if(isdigit(ch)) { //数字
token[0] = ch;
j = 1;
ch = getc(fin);
while(isdigit(ch)) {
token[j++] = ch;
ch = getc(fin);
}
token[j] = '\0';
fprintf(fout, "%s\t%s\n", "NUM", token);
} else if(strchr(singleword, ch) 0) { //singleword
token[0] = ch;
token[1] = '\0';
ch = getc(fin);
fprintf(fout, "%s\t%s\n", token, token);
} else if(strchr(doubleword, ch) 0) { //doubleword
token[0] = ch;
ch = getc(fin);
if(ch=='=' (token[0]==''||token[0]=='' || token[0] == '!')) {
token[1] = ch;
token[2] = '\0';
ch = getc(fin);
} else if((ch=='')||(ch=='|')||(ch=='=') ch==token[0]) {
token[1] = ch;
token[2] = '\0';
ch = getc(fin);
} else {
token[1] = '\0';
}
fprintf(fout, "%s\t%s\n", token, token);
} else if(ch == '/') { //注释
ch = getc(fin);
if(ch == '*') {
char ch1;
ch1 = getc(fin);
do {
ch = ch1;
ch1 = getc(fin);
} while((ch!='*'||ch1!='/') ch1!=EOF);
ch = getc(fin);
} else {
token[0] = '/';
token[1] = '\0';
fprintf(fout, "%s\t%s\n", token, token);
}
} else {
token[0] = ch;
token[1] = '\0';
ch = getc(fin);
es = 3;
fprintf(fout, "%s\t%s\n", "ERROR", token);
}
}
fclose(fin);
fclose(fout);
return es;
}
void main() {
int es = 0;
es = TESTscan();
if(es 0) {
printf("词法分析有错, 编译停止!\n");
} else {
printf("词法分析成功!\n");
}
}
Java代码到底是如何编译成机器指令的
编译器把一种语言规范转化为另一种语言规范的这个过程需要哪些步骤?回答这个问题需要参照《编译原理》,总结过程如下:
1)词法分析:读取源代码,一个字节一个字节的读进来,找出这些词法中我们定义的语言关键词如:if、else、while等,识别哪些if是合法的哪些是不合法的。这个步骤就是词法分析过程。
词法分析的结果:就是从源代码中找出了一些规范化的token流,就像人类语言中,给你一句话你要分辨出哪些是一个词语,哪些是标点符号,哪些是动词,哪些是名词。
2)语法分析:就是对词法分析中得到的token流进行语法分析,这一步就是检查这些关键词组合在一起是不是符合Java语言规范。如if的后面是不是紧跟着一个布尔型判断表达式。
语法分析的结果:就是形成一个符合Java语言规定的抽象语法树,抽象语法树是一个结构化的语法表达形式,它的作用是把语言的主要词法用一个结构化的形式组织在一起。这棵语法树可以被后面按照新的规则再重新组织。
3)语义分析:语法分析完成之后也就不存在语法问题了,语义分析的主要工作就是把一些难懂的,复杂的语法转化成更简单的语法。就如难懂的文言文转化为大家都懂的百话文,或者是注释一下一些不懂的成语。
语义分析结果:就是将复杂的语法转化为简单的语法,对应到Java就是将foreach转化为for循环,还有一些注释等。最后生成一棵抽象的语法树,这棵语法树也就更接近目标语言的语法规则。
4)字节码生成:将会根据经过注释的抽象语法树生成字节码,也就是将一个数据结构转化为另外一个数据结构。就像将所有的中文词语翻译成英文单词后按照英文语法组装文英文语句。代码生成器的结果就是生成符合java虚拟机规范的字节码。
怎么用java写一个词法分析器
首先看下我们要分析的代码段如下:
输出结果如下:
输出结果(a).PNG
输出结果(b).PNG
输出结果(c).PNG
括号里是一个二元式:(单词类别编码,单词位置编号)
代码如下:
?
1234567891011121314
package Yue.LexicalAnalyzer; import java.io.*; /* * 主程序 */public class Main { public static void main(String[] args) throws IOException { Lexer lexer = new Lexer(); lexer.printToken(); lexer.printSymbolsTable(); }}
?
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
package Yue.LexicalAnalyzer; import java.io.*;import java.util.*; /* * 词法分析并输出 */public class Lexer { /*记录行号*/ public static int line = 1; /*存放最新读入的字符*/ char character = ' '; /*保留字*/ HashtableString, KeyWord keywords = new HashtableString, KeyWord(); /*token序列*/ private ArrayListToken tokens = new ArrayListToken(); /*符号表*/ private ArrayListSymbol symtable = new ArrayListSymbol(); /*读取文件变量*/ BufferedReader reader = null; /*保存当前是否读取到了文件的结尾*/ private Boolean isEnd = false; /* 是否读取到文件的结尾 */ public Boolean getReaderState() { return this.isEnd; } /*打印tokens序列*/ public void printToken() throws IOException { FileWriter writer = new FileWriter("E:\\lex.txt"); System.out.println("词法分析结果如下:"); System.out.print("杜悦-2015220201031\r\n\n"); writer.write("杜悦-2015220201031\r\n\r\n"); while (getReaderState() == false) { Token tok = scan(); String str = "line " + tok.line + "\t(" + tok.tag + "," + tok.pos + ")\t\t" + tok.name + ": " + tok.toString() + "\r\n"; writer.write(str); System.out.print(str); } writer.flush(); } /*打印符号表*/ public void printSymbolsTable() throws IOException { FileWriter writer = new FileWriter("E:\\symtab1.txt"); System.out.print("\r\n\r\n符号表\r\n"); System.out.print("编号\t行号\t名称\r\n"); writer.write("符号表\r\n"); writer.write("编号 " + "\t行号 " + "\t名称 \r\n"); IteratorSymbol e = symtable.iterator(); while (e.hasNext()) { Symbol symbol = e.next(); String desc = symbol.pos + "\t" + symbol.line + "\t" + symbol.toString(); System.out.print(desc + "\r\n"); writer.write(desc + "\r\n"); } writer.flush(); } /*打印错误*/ public void printError(Token tok) throws IOException{ FileWriter writer = new FileWriter("E:\\error.txt"); System.out.print("\r\n\r\n错误词法如下:\r\n"); writer.write("错误词法如下:\r\n"); String str = "line " + tok.line + "\t(" + tok.tag + "," + tok.pos + ")\t\t" + tok.name + ": " + tok.toString() + "\r\n"; writer.write(str); } /*添加保留字*/ void reserve(KeyWord w) { keywords.put(w.lexme, w); } public Lexer() { /*初始化读取文件变量*/ try { reader = new BufferedReader(new FileReader("E:\\输入.txt")); } catch (IOException e) { System.out.print(e); } /*添加保留字*/ this.reserve(KeyWord.begin); this.reserve(KeyWord.end); this.reserve(KeyWord.integer); this.reserve(KeyWord.function); this.reserve(KeyWord.read); this.reserve(KeyWord.write); this.reserve(KeyWord.aIf); this.reserve(KeyWord.aThen); this.reserve(KeyWord.aElse); } /*按字符读*/ public void readch() throws IOException { character = (char) reader.read(); if ((int) character == 0xffff) { this.isEnd = true; } } /*判断是否匹配*/ public Boolean readch(char ch) throws IOException { readch(); if (this.character != ch) { return false; } this.character = ' '; return true; } /*数字的识别*/ public Boolean isDigit() throws IOException { if (Character.isDigit(character)) { int value = 0; while (Character.isDigit(character)) { value = 10 * value + Character.digit(character, 10); readch(); } Num n = new Num(value); n.line = line; tokens.add(n); return true; } else return false; } /*保留字、标识符的识别*/ public Boolean isLetter() throws IOException { if (Character.isLetter(character)) { StringBuffer sb = new StringBuffer(); /*首先得到整个的一个分割*/ while (Character.isLetterOrDigit(character)) { sb.append(character); readch(); } /*判断是保留字还是标识符*/ String s = sb.toString(); KeyWord w = keywords.get(s); /*如果是保留字的话,w不应该是空的*/ if (w != null) { w.line = line; tokens.add(w); } else { /*否则就是标识符,此处多出记录标识符编号的语句*/ Symbol sy = new Symbol(s); Symbol mark = sy; //用于标记已存在标识符 Boolean isRepeat = false; sy.line = line; for (Symbol i : symtable) { if (sy.toString().equals(i.toString())) { mark = i; isRepeat = true; } } if (!isRepeat) { sy.pos = symtable.size() + 1; symtable.add(sy); } else if (isRepeat) { sy.pos = mark.pos; } tokens.add(sy); } return true; } else return false; } /*符号的识别*/ public Boolean isSign() throws IOException { switch (character) { case '#': readch(); AllEnd.allEnd.line = line; tokens.add(AllEnd.allEnd); return true; case '\r': if (readch('\n')) { readch(); LineEnd.lineEnd.line = line; tokens.add(LineEnd.lineEnd); line++; return true; } case '(': readch(); Delimiter.lpar.line = line; tokens.add(Delimiter.lpar); return true; case ')': readch(); Delimiter.rpar.line = line; tokens.add(Delimiter.rpar); return true; case ';': readch(); Delimiter.sem.line = line; tokens.add(Delimiter.sem); return true; case '+': readch(); CalcWord.add.line = line; tokens.add(CalcWord.add); return true; case '-': readch(); CalcWord.sub.line = line; tokens.add(CalcWord.sub); return true; case '*': readch(); CalcWord.mul.line = line; tokens.add(CalcWord.mul); return true; case '/': readch(); CalcWord.div.line = line; tokens.add(CalcWord.div); return true; case ':': if (readch('=')) { readch(); CalcWord.assign.line = line; tokens.add(CalcWord.assign); return true; } break; case '': if (readch('=')) { readch(); CalcWord.ge.line = line; tokens.add(CalcWord.ge); return true; } break; case '': if (readch('=')) { readch(); CalcWord.le.line = line; tokens.add(CalcWord.le); return true; } break; case '!': if (readch('=')) { readch(); CalcWord.ne.line = line; tokens.add(CalcWord.ne); return true; } break; } return false; } /*下面开始分割关键字,标识符等信息*/ public Token scan() throws IOException { Token tok; while (character == ' ') readch(); if (isDigit() || isSign() || isLetter()) { tok = tokens.get(tokens.size() - 1); } else { tok = new Token(character); printError(tok); } return tok; }}
关于java词法分析源代码和java词法分析简单代码的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。