- 实验二 词法分析器的应用
- 文件上传题
- 1. 词法分析的应用:C++源程序的压缩和解压
【问题描述】
利用词法分析功能实现具有压缩和解压功能的C++源程序压缩器,并得到压缩文本
-
压缩器:为了提高C++源程序的可读性,C++程序在书写过程中加入了空行、空格、缩进、注释等。假设你想牺牲可读性,以节省磁盘空间,那么你可以存贮一个删除了所有不必要空格和注释的C++源程序的压缩文本。由于C++源程序是由一些具有特定功能的单词组成的,因此可以采用转换为编码的方法来进一步实现减小源文件大小的压缩功能。为了实现这一效果,我们可以先把C++源代码中的各类单词(记号)进行拼装分离,并进行编码的转换。
-
解压器:能够把通过压缩器压缩得到的C++源程序压缩文本进行重新解压并还原出除了被删除的所有不必要空格和注释的C++源程序。
说明: C++语言包含了几种类型的单词(记号):标识符,关键字,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等【详细的单词类别及单词组成规则见另外的文件说明】。
【实验要求】
要求应用程序应为Windows界面,在一个界面中可以实现压缩与解压两个功能。该界面应该具备的详细功能有:
1.打开一个C++源文件,并可以浏览该源程序。
2.压缩所打开的C++源程序
3.查看或浏览得到的压缩文本
4.打开一个C++源程序的压缩文本,并可以浏览该压缩文本。
5.解压该压缩文本,并可以浏览所解压出来的源程序。
【提交资料要求】
只能使用RAR文件或ZIP压缩文件进行提交。压缩文件内含文件夹及文件如下:
(1)源程序文件夹:内含整个实验的所有源程序文件和编译方法的说明介绍文件
(2)文档文件夹:内含实验的设计文档
(3)测试数据文件夹:内含所有的测试数据文件
(4)可执行程序文件夹:内含实验的可执行程序以及使用说明书。
源码:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Demo{
private static final int Start = 1;
private static final int Num = 2;
private static final int ID = 3;
private static final int EQ = 4;
private static final int NE = 5;
private static final int NM = 6;
private static final int NL = 7;
private static final int Coms = 8;
private static final int LineCom = 9;
private static final int MulCom1 = 10;
private static final int MulCom2 = 11;
private static final int Special = 12;
private static final int Done = 13;
private static final int Str = 14;
MoveButton bu;
public Demo(MoveButton bu){
this.bu=bu;
}
private enum TokenType {
Initial, ID, Special, Str, KeyWord
};
private String[] keyWords = new String[] {
"include", "define", "iostream", "int", "folat", "double",
"main", "if", "else", "for", "while", "do", "goto", "switch",
"case", "static", "cin", "cout" ,"using","using namespace std","private","protected","public","abstract","class","extends","final","implements",
"interface","native","new","static","strictfp","break","continue","return","do","while","if","else","for",
"instanceof","switch","case","default","boolean","byte","char","double","float","int","long","short",
"String","null","true","false","void","this","goto","printf","include"
};
private String [] special = {"{", "}", "[", "]", "(", ")",
"#", ",", ".", ";", ":", "\\",
"'", "\"", ">>", "<<", "!=", "=",
"==", "<=", ">=", "++", "--",};
private String [] arithmetic = {"+", "-", "*", "/", "%"};
private BufferedReader sourceFile;
private PrintWriter compressedFileWriter;
private TokenType preType = TokenType.Initial;
private StringBuilder compressedStr = new StringBuilder();
private static final int BUF_SIZE = 256;
private int bufSize = 0;
private String eachLine;
// 当前扫描行的字符序列
private char [] lineBuf = new char[BUF_SIZE];
// 当前扫描的行数
private int lineNum = 0;
// 当前行的字符下标
private int charPos = 0;
private boolean isEOF = false;
private void initial(){
bufSize = 0;
lineNum = 0;
charPos = 0;
isEOF = false;
}
void scanning(String file) throws Exception {
this.sourceFile = new BufferedReader(new FileReader(file));
this.initial();
while(!isEOF) {
getToken();
}
System.out.println("========================> end scanning ...");
}
private char getNextChar() th