编译原理实验3 词法分析器DFA实现

  最近重新学习了Java,虽然才看到核心卷的继承篇,但是感觉Java的封装与复用十分便利,于是准备改用Java进行编译原理实验的开发。

实验要求:

实验三:词法分析器2—自动机方法

 

实验目的:

通过编写一个扫描器(词法分析器),掌握词法分析器的构造方法之一: 自动机方法(模拟DFA)

 

实验要求:

1、本词法分析器的任务:

(1)进行C语言子集LC程序的词法分析,C语言的子集LC={C语言常用的关键字10-15个 }∪{常数}∪{变量,即标识符}∪{关系运算符}∪{其它运算符}∪{界符}。输入为任意的C语言程序源文件,经过分析后产生一个.txt中间文件,供后续语法分析使用,该分析器设定6种数据类型,分别为关键字、标识符、常数、关系运算符、其它运算符和界符,每种类型包含的关键字个数和符号自行定义,C语言常用的关键字和符号都要包含在内,(注:若按其它方式进行类型划分请在实验报告中注明类型划分方案)。

(2)其中关系运算符、标识符和常数的识别用模拟DFA算法,其它符号自行选择方法。常数限定构词规则为如下格式:数字.数字,标识符限定构词规则为:字符后接字符或数字,关系运算符按课堂讲述的构词规则构成。

(3)输出以源程序代码的一行为输出的一行进行输出。输出结果可以与实验2相同。也可以按不同的分类方式输出。

(4)给出标识符符号表内容,对出现的标识符分别标记为id0, id1,id2……。

(5)给出至少2种错误提示:如非法word(err1)、小数点后无数字(err2)、注释符号不配对(err3)、其它你认为目前编译器应该给出的词法错误提示,参考教材P16。

 

2、实验报告要求:

(1)进行词法分析器的测试:测试例程(一段C语言源程序)、测试结果与测试结果分析。

(2)实验报告中要给出正规式设计、NFA、DFA、DFA最小化、状态转换矩阵(以上各项写在实验原理中)、代码编写、测试例子4个(如下例给出的2个例子)、测试结果与测试结果分析逐项给予说明。

 

第一段:

(1)/*测试用例

(2)for (i=1;i<=100;i++)

(3){     printf("%d ", i ); 

(4)}

over

运行词法分析程序后,得到显示结果如下的.txt文件:  

(1) (/*,30)(?err1

(2) (for,16) ((,err) (i,id0) (=,31) (1,41) (;,22) (i , id0) (<=,err) (100,42) (;,22) (i , id 0) (++,37) (),err)

(3) ({,err) (Printf, id1) ((,err) (" ,21) (%,36) (d, id2) (" ,21) (,,err) (i, id 0) ( ),err) ( ;,22)

(4)( },err)

over

变量表(标识符表)中的内容为:

id 0,i:

 id1,printf,

id 2,d

 

一、文件的读写

首先进行对txt文本的读写:

import java.io.*;
import java.util.ArrayList;


public class IoTxt {
	static ArrayList<String> inTxt(String s) {
		ArrayList<String> al=new ArrayList<String>();
		String pathname = s; // 绝对路径或相对路径都可以,写入文件时演示相对路径,读取以上路径的input.txt文件
	    try (FileReader reader = new FileReader(pathname);
	         BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
	        ) 
	    {
	    	String line;
	        while ((line = br.readLine()) != null) {
	        // 一次读入一行数据
	        al.add(line);
	      }
	    } catch (IOException e) {
	            e.printStackTrace();
	        }
	    return al;
	}
	
	static void outTxt(String s) {
        try {
            File writeName = new File("D:\\output.txt"); // 绝对路径,如果没有则要建立一个新的output.txt文件
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            try (FileWriter writer = new FileWriter(writeName);
                 BufferedWriter out = new BufferedWriter(writer)
            ) {
                out.write(s); 
                out.flush(); // 把缓存区内容压入文件
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }	
	}
	
	//测试函数
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		IoTxt.outTxt("HelloWorld!");
		ArrayList<String> al=IoTxt.inTxt("D:\\output.txt");
		for(String s:al) {
			System.out.println(s);
		}
	}

}

  以上是1.0版本,在IoTxt类中写了两个静态方法inTxt和outTxt,一个用来将输入地址参数的txt文本逐行转换成String类型置入一个ArrayList中并返回,一个将输入的String参数写入D:\\output.txt中。

 1.0版本有一个存在问题:output文本中每次都是用一个String重写文本,而实验需求将每行的分析结果(String)写入,即多个String。

 2.0版本的outTxt方法以及测试方法:

	static void outTxt(ArrayList<String> al) {
        try {
            File writeName = new File("D:\\output.txt"); // 绝对路径,如果没有则要建立一个新的output.txt文件
            writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖
            try (FileWriter writer = new FileWriter(writeName);
                 BufferedWriter out = new BufferedWriter(writer)
            ) {
                for(String s:al) {
                	out.write(s+"\r\n");	// \r\n即为换行
                }
                out.flush(); // 把缓存区内容压入文件
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }	
	}
	
	//测试函数
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ArrayList<String> al=new ArrayList<String>();
		al.add("Hello");
		al.add("World!");
		IoTxt.outTxt(al);
		
		al=IoTxt.inTxt("D:\\output.txt");
		for(String s:al) {
			System.out.println(s);
		}
	}

实现功能需求。

参考链接:Java读取txt文件和写入txt文件

https://blog.csdn.net/nickwong_/article/details/51502969

二、DFA类的设计

功能需求:将文本读到的ArrayList里面保存的每行数据进行词法分析。

未完待续

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值