词法分析器 Java完整代码版

article/2025/11/1 6:29:52

想了解更多内容,移步至编译原理专栏

==========================2021.12.22 更新===================================

整理了一下代码,同步到了gitee

https://gitee.com/godelgnis/lrparserhttps://gitee.com/godelgnis/lrparser

 --------------------------------------------------分割线---------------------------------------------------------------------

这学期选修了编译原理,用的是電子工业出版社出版的《编译原理(第4版)》

最近做了第一次实验词法分析器,是教材后面的附录c.1的内容,根据下面的图创建词法分析器

课本给出了C语言版本的词法分析器,但是看着挺蛋疼的,感觉C语言的指针很烦,于是做了一个Java版本的,说简单也挺简单的(其实大部分是把C语言版本的代码直接复制过来)哈哈。

老师的实验要求是

所以对书上的代码输入输出的代码进行修改,另外,书上代码中的种别码与上面的表格不是对应的,所以也要进行修改

废话不多说,直接上代码

package codescanner;public class Word {private int typenum;	//种别码private String word;	//扫描得到的词public int getTypenum() {return typenum;}public void setTypenum(int typenum) {this.typenum = typenum;}public String getWord() {return word;}public void setWord(String word) {this.word = word;}
}
public class CodeScanner {private static String _KEY_WORD_END = "end string of string";private int charNum = 0;	private Word word;private char[] input = new char[255];private char[] token = new char[255];private int p_input=0;private int p_token=0;private char ch;private String[] rwtab = {"begin","if","then","while","do","end","",_KEY_WORD_END};public CodeScanner(char[] input) {this.input = input;}/*** 取下一个字符* @return*/public char m_getch() {if(p_input < input.length) {ch = input[p_input];p_input++;}return ch;}/*** 如果是标识符或者空白符就取下一个字符*/public void getbc() {while((ch == ' ' || ch == '\t') && p_input < input.length) {ch=input[p_input];p_input++;}}/*** 把当前字符和原有字符串连接*/public void concat() {token[p_token] = ch;p_token++;token[p_token] = '\0';}public boolean letter() {if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return true;elsereturn false;}public boolean digit() {if(ch>='0'&&ch<='9')return true;elsereturn false;}/*** 回退一个字符*/public void retract() {p_input--;}/*** 将token中的数字串转换成二进制值表示* @return*/public String dtb() {int num = token[0] - 48;for(int i = 1; i < p_token; i++) {num = num * 10 + token[i] - 48;}StringBuilder result = new StringBuilder();while(num>0) {int r = num % 2;int s = num / 2;result.append(r);num = s;}return result.reverse().toString();}/*** 查看token中的字符串是否是关键字,是的话返回关键字种别编码,否则返回10* @return*/public int reserve() {int  i=0;while(rwtab[i].compareTo(_KEY_WORD_END)!=0) {if(rwtab[i].compareTo(new String(token).trim()) == 0) {return i+1;}i++;}return 10;}/*** 能够识别换行,单行注释和多行注释的* 换行的种别码设置成30* 多行注释的种别码设置成31* @return*/public Word scan() {token = new char[255];Word myWord = new Word();myWord.setTypenum(10);myWord.setWord("");p_token=0;m_getch();getbc();if(letter()) {while(letter()||digit()) {concat();m_getch();}retract();myWord.setTypenum(reserve());myWord.setWord(new String(token).trim());return myWord;}else if(digit()) {while(digit()) {concat();m_getch();}retract();myWord.setTypenum(11);myWord.setWord(new String(token).trim());	//输出token中的数字串字符形式
//			myWord.setWord(dtb());						//输出token中的数字串10进制值的二进制字符串形式return myWord;}else switch (ch) {case '=':myWord.setTypenum(25);myWord.setWord("=");return myWord;case '+':myWord.setTypenum(13);myWord.setWord("+");return myWord;case '-':myWord.setTypenum(14);myWord.setWord("-");return myWord;case '*':myWord.setTypenum(15);myWord.setWord("*");return myWord;case '/':m_getch();//识别单行注释if (ch == '/') {while(m_getch() != '\n');myWord.setTypenum(30);myWord.setWord("\\n");return myWord;}//识别多行注释if(ch=='*') {String string = "";while(true) {if (ch == '*') {if (m_getch() == '/') {myWord.setTypenum(31);myWord.setWord(string);return myWord;}retract();}if (m_getch() == '\n') {string += "\\n";}}}retract();myWord.setTypenum(16);myWord.setWord("/");return myWord;case ':':m_getch();if(ch=='=') {myWord.setTypenum(18);myWord.setWord(":=");return myWord;}retract();myWord.setTypenum(17);myWord.setWord(":");return myWord;case '<':m_getch();if(ch=='=') {myWord.setTypenum(22);myWord.setWord("<=");return myWord;}else if (ch == '>') {myWord.setTypenum(21);myWord.setWord("<>");return myWord;}retract();myWord.setTypenum(20);myWord.setWord("<");return myWord;case '>':m_getch();if(ch=='=') {myWord.setTypenum(24);myWord.setWord(">=");return myWord;}retract();myWord.setTypenum(23);myWord.setWord(">");return myWord;case ';':myWord.setTypenum(26);myWord.setWord(";");return myWord;case '(':myWord.setTypenum(27);myWord.setWord("(");return myWord;case ')':myWord.setTypenum(28);myWord.setWord(")");return myWord;case '\n':myWord.setTypenum(30);myWord.setWord("\\n");return myWord;case '#':myWord.setTypenum(0);myWord.setWord("#");return myWord;default:concat();myWord.setTypenum(-1);myWord.setWord("ERROR INFO: WORD = \"" + new String(token).trim() + "\"");return myWord;}}}
package codescanner;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Scanner;public class Analyzer {private File inputFile;private File outputFile;private String fileContent;private ArrayList<Word> list = new ArrayList<>();public Analyzer(String input,String output) {inputFile = new File(input);outputFile = new File(output);}/*** 从指定的文件中读取源程序文件内容* @return*/public String getContent() {StringBuilder stringBuilder = new StringBuilder();try(Scanner reader = new Scanner(inputFile)) {while (reader.hasNextLine()) {String line = reader.nextLine();stringBuilder.append(line + "\n");}} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return fileContent = stringBuilder.toString();}/*** 先将源程序中的注释和换行替换成空串* 然后扫描程序,在程序结束前将扫描到的词添加到list中* 最后把扫描结果保存到指定的文件中*/public void analyze(String fileContent) {int over = 1;Word word = new Word();//fileContent = fileContent.replaceAll("//.*\n", "") // 去除字符串fileContent中所有的单行注释 与 换行//		.replaceAll("/\\*{1,2}[\\s\\S]*?\\*/", ""); // 去除字符串fileContent中所有的多行注释//现在不用正则表达式也可以识别换行和单行注释和多行注释了CodeScanner scanner = new CodeScanner(fileContent.toCharArray());while (over != 0) {word = scanner.scan();
//			System.out.println("(" + word.getTypenum() + " ," + word.getWord() + ")"); //在控制台输出结果list.add(word);over = word.getTypenum();}saveResult();}/*** 将结果写入到到指定文件中* 如果文件不存在,则创建一个新的文件* 用一个foreach循环将list中的项变成字符串写入到文件中*/public void saveResult() {if (!outputFile.exists())try {outputFile.createNewFile();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}try(Writer writer = new FileWriter(outputFile)){for (Word word : list) {writer.write("(" + word.getTypenum() + " ," + word.getWord() + ")\n");}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {Analyzer analyzer = new Analyzer("input.txt","output.txt");//输入输出可自己修改,文件放在当前文件夹下,刷新项目就可以看到了analyzer.analyze(analyzer.getContent());}
}

测试数据

begin x:=9; //while there is a annotationif /***编译原理大法好!*/x>0  then   x:=2*x+1/3; 
end
#

结果

觉得写得还可以得话,可以给我点个赞呀:)

===========================2020/12/1更新==================================

补充一下,项目结构,input.txt 和 output.txt 是和 src 目录同等级的,而且这个目录是可以自己改的,在main函数里自己改下路径,想放哪放哪,我当时这么写就是为了图方便而已。。。。。

input.txt 需要自己手动创建,内容需要自己输入,output.txt可以不创建(文件不存在会自动创建),它是用来保存分析结果的。

不要再私信我input或者output文件的问题了,代码不难,你稍微有点耐心看下就能看懂了(基本流程的注释都写了。。。。),要是看不懂,那么你可能需要加强一下Java基础了。

 


http://chatgpt.dhexx.cn/article/hVtZ4Me3.shtml

相关文章

编译原理——词法分析器(C/C++代码实现)

目录 0 实验目的&#xff1a; 1 实验要求&#xff1a; 2 实验内容&#xff1a; 3 实验思路&#xff1a; 4 实验代码&#xff1a; 5 实验结果&#xff1a; 6 实验总结&#xff1a; 7 实验程序以及实验报告下载链接&#xff1a; 0 实验目的&#xff1a; 设计、编制、实现…

词法分析器的构成(含源代码)

标题&#xff1a;词法分析器 本人最近在学习编译原理&#xff0c;刚刚学到词法分析器&#xff0c;心想着挺好玩&#xff0c;就想着自己写一个&#xff0c;奈何一没有系统的学过c语言&#xff0c;只是粗略的看过一遍K&R的c语言书&#xff0c;所以水平尚浅&#xff0c;代码有…

java实现词法分析器

实现词法分析器 实验内容要求 一、实验目的 加深对词法分析器的工作过程的理解&#xff1b;加强对词法分析方法的掌握&#xff1b;能够采用一种编程 语言实现简单的词法分析程序&#xff1b;能够使用自己编写的分析程序对简单的程序段进行词法分 析。 二、实验内容 自定义一…

python实现词法分析器

基于python3 实现一个简单的词法分析器。 主要使用的库&#xff1a;正则表达式、tkinter 识别关键字&#xff0c;标识符&#xff0c;运算符&#xff0c;分界符&#xff0c;数字&#xff08;整数和浮点数&#xff09; 当以数字开头时报错&#xff0c;标识符超过8个字符长度时报…

词法分析器设计与实现

开篇 编译&#xff0c;简单的说&#xff0c;就是把源程序转换为可执行程序。从hello world 说程序运行机制 里面简单的说明了程序运行的过程&#xff0c;以及一个程序是如何一步步变成可执行文件的。在这个过程中&#xff0c;编译器做了很多重要的工作。对底层该兴趣的我&…

[编译原理]词法分析器的分析与实现

词法分析概述&#xff1a; 编译程序要对高级语言编写的源程序进行分析和合成&#xff0c;生成目标程序。词法分析是对源程序进行的首次分析&#xff0c;实现词法分析的程序成为词法分析程序(或词法分析器)&#xff0c;也称扫描器。像用自然语言书写的文章一样&#xff0c;源程…

词法分析器【编译原理】

实验内容&#xff1a; 基于TEST语言设计相应的词法输入器并且输出二元组 实验目的&#xff1a; 1、理解词法分析器的基本功能 2、理解简单的词法规则的描述方法 3、理解状态转化图及其实现 4、能够编写简单的词法分析器 实验原理&#xff1a; 根据DFA构造词法分析程序 1、…

词法分析器的实现

原文地址为&#xff1a; 词法分析器的实现 开篇 编译&#xff0c;简单的说&#xff0c;就是把源程序转换为可执行程序。从hello world 说程序运行机制 里面简单的说明了程序运行的过程&#xff0c;以及一个程序是如何一步步变成可执行文件的。在这个过程中&#xff0c;编译器…

词法分析器原理简介

词法分析器原理简介 词法分析器读取有字符串组成的输入流&#xff0c;并产生包含单词的输出流&#xff0c;每个单词都标记了其语法范畴&#xff08;syntactic category&#xff09;或类型&#xff0c;等效于英文单词的词类。为了完成这种聚集和分类操作&#xff0c;词法分析器…

编译原理——词法分析器 C++实现

词法分析器 实验目的单词分类表单词结构描述单词状态转换图算法描述程序结构源代码实验结果 实验目的 对C语言的一个子集设计并实现一个简单的词法分析器&#xff0c;掌握利用状态转换图设计词法分析器的基本方法。利用该词法分析器完成对源程序字符串的词法分析。培养团队合作…

词法分析器(纯c语言)

一、原文章&#xff1a;词法分析器&#xff08;分析C语言&#xff09; 二、该词法分析器种别码表 三、词法分析器实现思路描述&#xff1a; 1.首先用一个数组来存储txt文本中非空白字符&#xff0c;并将存储字符的个数记录下来。 2.用scan()函数扫描数组中的字符&#xff0c…

编译原理--词法分析器(python语言实现)

词法分析器 最近在学习编译原理。由于实验要求有词法分析器&#xff0c;这里我就先记录一下词法分析器实现过程以及具体思路。 目标语言 此处我选择的目标语言是c语言的子集来进行词法分析。 实现语言 此处我选用的语言是python&#xff0c;主要还是考虑到python的数据结构…

词法分析器--C实现

实验目的&#xff1a; 编制一个读单词过程&#xff0c;从输入的源程序中&#xff0c;识别出各个具有独立意义的单词&#xff0c;即基本保留字、标识符、常数、运算符、分隔符五大类(可自主添加类别)。并依次输出各个单词的内部编码及单词符号自身值。 程序及其子程序&#xff1…

c语言实现词法分析器

词法分析器的功能:输入源程序&#xff0c;输出单词字符。单词字符一般可以分为下面五种。 &#xff08;1&#xff09;关键字 是由程序语言定义的具有固定意义的标识符。有时称这些标识符为保留字或者基本字。例如c语言中的int,char,define,strcut,double,if,else.等等 &#xf…

词法分析器(分析C语言)

问题描述&#xff1a; 用C或C语言编写一个简单的词法分析程序&#xff0c;扫描C语言小子集的源程序&#xff0c;根据给定的词法规则&#xff0c;识别单词&#xff0c;填写相应的表。如果产生词法错误&#xff0c;则显示错误信息、位置&#xff0c;并试图从错误中恢复。简单的恢…

词法分析器(c++)

前景提示&#xff1a; 个人觉得单纯是用来完成实验报告的话还行&#xff0c;但仅做参考&#xff0c;因为本人的编程水平有限&#xff0c;怕误人子弟。 本次代码支持以下操作&#xff1a; 单行注释 多行注释 文件形式输入 种别码可以在文件中自由修改 单词字符串识别支持…

词法分析——词法分析器的作用

目录 综述 正文 1 词法分析与语法分析 2 词法单元、模式和词素 3 词法单元的属性 4 词法错误 综述 词法分析是编译的第一阶段。词法分析器的主要作用是读入源程序的输入字符、将它们组成词素&#xff0c;生成并输出一个词法单元序列&#xff0c;每个词法单元对应一个词素。…

词法分析器

词法分析&#xff08;Lexical Analysis&#xff09; 词法分析器在英文中一般叫做 Tokenizer。 有一个计算模型&#xff0c;叫做有限自动机&#xff08;Finite-state Automaton&#xff0c;FSA&#xff09;&#xff0c;或者叫做有限状态自动机&#xff08;Finite-state Machin…

编译原理——词法分析器

1 概述 设计、编制并调试一个简单的C语言词法分析程序&#xff0c;掌握利用状态转换图设计词法分析器的基本方法&#xff0c;利用该词法分析器完成对源程序字符串的词法分析。通过对该词法分析器的设计&#xff0c;加深对词法分析原理、状态转换图等编译原理知识的理解。 2 使…

编译原理词法分析器(C/C++)

前言&思路 词法分析器不用多说&#xff0c;一开始我还不知道是什么样的&#xff0c;看了下别人的博客&#xff0c;再看看书&#xff0c;原来是输出二元组&#xff0c;这不就是字符串操作嘛。然后细看几篇博客&#xff0c;发现大都是用暴力判断来写的。我对代码重复性比较高…