Java实现简易的词法分析器

Java实现简易的词法分析器此次也是课题需要 才写了这么一个项目 编译原理课你懂的 由于个人比较喜欢 Java 因此写了一个 Java 版本简易的词法分析器 也是因为 Java 对数组的使用比较随意 注意 没有出错处理 如 9int 或是 int23 等等一系列错误是检测不出来的 但是可以检测小数和注释的错误 错误种类太多太麻烦 就没有处理了 实验要求如下 实验一 nbsp 词法分析程序设计 实验要求 对一个简单的语言的子集编制一个一遍扫描

此次也是课题需要,才写了这么一个项目,编译原理课你懂的.

由于个人比较喜欢Java,因此写了一个Java版本简易的词法分析器.(也是因为Java对数组的使用比较随意)

注意:没有出错处理,如 9int,或是 int 23等等一系列错误是检测不出来的.

实验要求如下:

实验一  词法分析程序设计

【实验要求】

对一个简单的语言的子集编制一个一遍扫描的词法分析程序。

【实验内容】

1、待分析的简单语言词法

1)关键字

可以自由添加。如C语言的关键字:main if else int char return void while等。

(2)标识符(ID

ID→letter(letter|digit)* Letter→a||z|A||Z digit→0||9

(3)常数(可以先以整形常数为例)

NUM→digit(digit)* digit→0||9

(4)运算符

C语言中的运算符= + – * / < <= > >= == !=等。

(5)界符

C语言中的; : , { } [ ] ( )等。空格由空白、制表符和换行符组成。空格一般用来分隔关键字、IDNUM、运算符和界符。词法分析阶段空格通常被忽略。

2、各种单词类别及对应的种别编码

关键字设置为0~99,如“main”设置为0,“if”设置为1,……;

标识符设置为100

常数设置为101~109,如整形常数设置为101,小数常数设置为102,……;

运算符设置为110~149,如“=”设置为111,“+”设置为112,……;

界符设置为150~159,如“;”设置为150,“,”设置为151,……。

例如:对源程序int x =9; if (x>0)  x=2*x+1/3; 经词法分析后输出如下序列:(3int) (1,‘x’) (4=) (29) ……


输入截图:

Java实现简易的词法分析器

运行结果截图:

Java实现简易的词法分析器

源代码:

package Analyzer; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.*; import java.io.*; public class LexicalAnalyzer { //将txt文件转为数组 public String txt2String(File file) throws IOException { StringBuilder result =new StringBuilder(); try { BufferedReader br= new BufferedReader(new FileReader(file)); String s=null; while((s=br.readLine())!=null){ result.append(System.lineSeparator()+s); } br.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result.toString(); } //对文本进行预处理 public char[] preTreatment(char[] sourcefile) { char []afterfile = new char[10000]; int index=0; if(sourcefile.length!=0) { for(int i=0;i 
   
     ='a'&&c<='z')||(c>='A'&&c<'Z')) { return true; } else return false; } //判断是否为保留字,并返回编号 public int isReserve(String s,String []reserve) { int index=-1; for(int i=0;i 
    
      ='0'&&c<='9') { return true; } else return false; } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //保留字 String []reserve={"if","else","while","throw","this","int","String","char","double","float","this", "static","public","private","default","switch","catch","void","try","return"};//0~99 //运算符 String []operator={"+","-","*","/","++","--","==","!=",">","<",">=", "<=","&&","||","!","&","|","^","~","<<",">>",">>>","+=","="};//110~149 //界符 char []divide={'<','>','(',')','{','}','[',']','\'','"',',',';','?','/','\\',':','.'};//150~无穷 LexicalAnalyzer la=new LexicalAnalyzer(); //源代码的txt文件 File file=new File("D://Source.txt"); //将txt格式的源文件放入sourcefile的字符数组中 String source=la.txt2String(file); char sourcefile[] = source.toCharArray(); //将源代码进行预处理,去掉注释和换行符 char afterfile[]=la.preTreatment(sourcefile); //index记录源代码的字符数组扫描到的数组下标 int index=0; //temp用于存储临时的字符串 String temp=""; //当未扫描到终结符则一直往下扫描 while(afterfile[index]!='\0'){ //当开头为字母时,可能为保留字或是标识符 if(la.isLetter(afterfile[index])) { temp+=afterfile[index]; //当下一个字符不为字母或数字,则停止扫描,并将扫描结果存入temp while(la.isLetter(afterfile[index+1])||la.isDigit(afterfile[index+1])) { index++; temp+=afterfile[index]; } //将temp与保留字数组匹配,匹配成功即为保留字,否则为标识符 if(la.isReserve(temp, reserve)!=-1) System.out.println("保留字:("+la.isReserve(temp, reserve)+","+temp+")"); else System.out.println("标识符:("+100+","+temp+")"); } //当开头为数字时,可能为整数或小数 else if(la.isDigit(afterfile[index])) { temp+=afterfile[index]; while(la.isDigit(afterfile[index+1])) { index++; temp+=afterfile[index]; } //若在数字后有小数点,继续判断 if(afterfile[index+1]=='.') { index++; //小数点后无数字,检测出错 if(!la.isDigit(afterfile[index+1])){ System.out.println("此处有误,小数点后无数字"); temp=""; break; } //小数点后有数字,检测为小数 else { temp+=afterfile[index]; while(la.isDigit(afterfile[index+1])) { index++; temp+=afterfile[index]; } } System.out.println("小数常数:("+102+","+temp+")"); } //无小数点,检测为整数 else { System.out.println("整数常数:("+100+","+temp+")"); } } //既不是数字也不是字母也不是空格,则为界符或运算符,跳过空格 else if(afterfile[index]!=' ') { temp+=afterfile[index]; /*由于界符只有一个字符长度,则temp放入一个字符后直接开始匹配界符数组, * 匹配成功则continue循环,匹配失败则继续扫描 */ if(la.isDivide(temp, divide)!=-1) { System.out.println("界符:("+la.isDivide(temp, divide)+","+temp+")"); temp=""; index++; continue; } //判断是否为运算符 else { //若下一个字符也是符号类型则加入temp while((la.isDivide(afterfile[index+1]+"", divide)==-1)&&(la.isDigit(afterfile[index+1])==false) &&(la.isLetter(afterfile[index+1])==false)) { index++; temp+=afterfile[index]; } //与运算符数组匹配,匹配成功,则为运算符,失败,则可能出现了检测不了的字符。 if(la.isOperator(temp, operator)!=-1) System.out.println("运算符:("+la.isOperator(temp, operator)+","+temp+")"); else System.out.println("无法识别,可能为中文字符"); } } temp=""; index++; } } } 
     
   


 






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223193.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午2:38
下一篇 2026年3月17日 下午2:39


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号