⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text.java

📁 词法分析器 可以识别c++的源码,自动生成词法分析表, 在分析结束后会指出源代码中可能的错误 待分析的源代码要以 *源代码.txt的格式保存
💻 JAVA
字号:
/*  词法分析的主程序
  *  目前为单元测试程序
*/
package accidenceAnalyse;

import java.util.*;
import java.io.*;
import java.util.regex.*;

public class Text
{
	private Text(){}
	public void printTokenTable() {
		for (TokenTable table : tokenList)
		{
			System.out.println(table);
		}
	}
	
	public void printError() {
		for (String errorStr : errorList)
		{
			System.out.println(errorStr);
		}
	}	
	/* 列出所有的有待分析的源代码文件
	  * 要用.txt格式放在test1文件夹下!   */
	public int DirectryList() {
		File path = new File(".");
		allFiles = path.list(filter(fileNameStr));
		if ( allFiles.length == 0)
		{
			System.out.println("不存在待分析的源代码文件!");
			return 10000;
		}
		int fileNumber= 1;
		Integer i = 0;
		for (String file : allFiles)
		{
				System.out.print("  "+fileNumber+":   "+file+"         ");
				if ((++i).equals(3))
				{
					i = 0;
					System.out.println();
				}
				fileNumber++;
		}
		System.out.println("\r\n\r\n\r\n请选择要进行词法分析的文件,输入文件名前面的编号!");
		BufferedReader read = new BufferedReader(new InputStreamReader(System.in)); 
		while(true)
		{
			try {
				String choice = read.readLine().trim();
				if(choice.matches("\\d+"))
					return Integer.valueOf(choice) ;
				else
				{
					System.out.println("输入错误!重新输入!");
				}
			} catch(IOException e) {
				//System.out.println("不存在待分析的源代码文件!");
				System.out.println("出现异常!");
			}
		}
	}
	
	public static FilenameFilter filter(final String fileNameStr) {
		return new FilenameFilter(){
			private Pattern pattern = Pattern.compile(fileNameStr);
			public boolean accept(File dir,String name){
				return pattern.matcher(name).matches();
			}
		};
	}
	
	/*  词法分析阶段 */
	public void BeginAnalyse(int fileNO) throws IOException {
		try{
			BufferedReader inputFile = new BufferedReader(new FileReader(allFiles[fileNO-1]));
			try{
				int ASCII;
				while ((ASCII = inputFile.read())!= -1)
				{
					if (ASCII != 32)
					{
						if (ASCII == 10 || ASCII == 13) {
							if(ASCII == 10)	// 换行了
								textLine++;
								continue;
						}
						else
							judgeWhichToAnalyse(ASCII , inputFile);  // 判断要调用哪一个分析(标识符,关键字,数字....)
					} 
				}
			}finally{
				inputFile.close();
			}
		}catch(Exception e){
			System.out.println("源代码文件打开失败!");
		}
	}
	
	private void judgeWhichToAnalyse(int ASCII , BufferedReader inputFile) throws IOException {
		if ((""+(char)ASCII).matches("[_a-zA-Z]")) 
			IdentifierAnalyse(ASCII , inputFile);
		else if ((""+(char)ASCII).matches("\\d"))
			ConstAnalyse(ASCII , inputFile,1);
		else if ((""+(char)ASCII).matches("\""))
			ConstAnalyse(ASCII , inputFile,2);
		else if ((""+(char)ASCII).matches("\'"))
			ConstAnalyse(ASCII , inputFile,3);
		else if ((""+(char)ASCII).matches("\\W"))
			OperationAnalyse(ASCII , inputFile);
	}
	/*   标识符 以及 关键字 的分析入口*/
	public void IdentifierAnalyse(int ASCII , BufferedReader inputFile) throws IOException {
		ArrayList<Character> array= new ArrayList<Character>(Arrays.asList((char)ASCII)); 
		int WordASCII;
		int strLine = textLine;
		boolean willOperationAnalyse = false;
		while ((WordASCII = inputFile.read())!= 32)		// 第一种结束情况就是遇到空格
		{
			if ((""+(char)WordASCII).matches("[_\\w]"))
				array.add((char)WordASCII);
			else if ((""+(char)WordASCII).matches(";|\\+|\\-|\\*|/|%|\\(|\\)|,|\\.|\\{|\\}|\"|\'|\\[|\\]|\\?|=|\\||&|~|^")){  //所有可能跟在标识符后面的字符    结束的第二种情况
//				OperationAnalyse(WordASCII , inputFile);
				willOperationAnalyse = true;
				break;
			}
			else if (WordASCII == 10) { // 换行了	结束的第三种情况
					textLine++;
					break;
			}
			else if (WordASCII == -1)
				break;
			else
				array.add((char)WordASCII);
		}
		String identify ="";
		for (char c : array){
			identify += c;
		}
		token[0].analyse(identify, tokenList , errorList , strLine);
		if (willOperationAnalyse)
			OperationAnalyse(WordASCII , inputFile);
	}
	
	public void ConstAnalyse(int ASCII , BufferedReader inputFile , int type) throws IOException {
		int WordASCII;
		int strLine = textLine;
		switch (type)
		{
			case 1:	// 分析数字常量
			{
				ArrayList<Character> array= new ArrayList<Character>(Arrays.asList((char)ASCII));
				boolean isFloat = false , willOperationAnalyse = false;
				while ((WordASCII = inputFile.read())!= 32)		// 第一种结束情况就是遇到空格
				{
					if ((""+(char)WordASCII).matches("[xoFfUuEeLl]|\\d|\\.")){
						if ((""+(char)WordASCII).matches("[Ee]"))
							isFloat = true;		// 如果搜索中发现了 E 或 e,表明它可能是一个浮点数
						array.add((char)WordASCII);
					}
					else if ((""+(char)WordASCII).matches(";|\\+|\\-|\\*|/|%|\\(|\\)|,|\\{|\\}|\"|\'|\\[|\\]|\\? |=|\\||&|~|^")){  //所有可能跟在标识符后面的字符    结束的第二种情况
						if ((""+(char)WordASCII).matches("\\+|\\-")){
							
							if (isFloat){		//  如果 这个+/-紧跟在 e 或 E之后,那它就是一个浮点数
								array.add((char)WordASCII);
								isFloat = false;
								continue;
							}
							else{
								willOperationAnalyse = true;
								break;
							}
						}
						else{
							isFloat = false;
							willOperationAnalyse = true;
							break;
						}
					}
					else if (WordASCII == 10) { // 换行了	结束的第三种情况
							textLine++;
							break;
					}
					else if (WordASCII == -1)
						break;
				}
				String identify ="";
				for (char c : array){
					identify += c;
				}
				token[1].analyse(identify, tokenList , errorList , strLine);
				if (willOperationAnalyse)
					OperationAnalyse(WordASCII , inputFile);
				break;
			}
			case 2: //  分析字符串常量
			{
				ArrayList<Character> array= new ArrayList<Character>();
				boolean isRight = true;
				while ((WordASCII = inputFile.read())!= 34){		// 第一种结束情况就是遇到双引号
					if (WordASCII == 10) { // 换行了	结束的第二种情况
						String identify ="";
						for (char c : array){
							identify += c;
						}
						String errorStr = "第"+strLine+"行:  字符串"+identify+"没有正确结束,缺少 \"";
						errorList.add(errorStr);
						textLine++;
						isRight = false;
						break;
					}
					else if (WordASCII == -1){
						String identify ="";
						for (char c : array){
							identify += c;
						}
						String errorStr = "第"+strLine+"行:  字符串"+identify+"没有正确结束,缺少 \"";
						errorList.add(errorStr);
						isRight = false;
						break;
					}
					array.add((char)WordASCII);
				}
				if (isRight){
					String identify ="";
					for (char c : array){
						identify += c;
					}
					tokenList.add(new TokenTable(3 , identify));
				}
				break;
			}
			case 3: //  分析字符常量
			{
				ArrayList<Character> array= new ArrayList<Character>();
				WordASCII = inputFile.read();
				if (WordASCII == 10) { // 换行了	结束的第二种情况
					String errorStr = ""+strLine+"行:  字符没有正确结束,缺少\'";
					errorList.add(errorStr);
					textLine++;
				}
				else if (WordASCII == -1){
					String errorStr = ""+strLine+"行:  字符没有正确结束,缺少\'";
					errorList.add(errorStr);		
					break;
				}				
				else{
					array.add((char)WordASCII);
					WordASCII = inputFile.read();		// 再读一个
					if (WordASCII != 39){			// 不是单个字符了
						String identify ="";
						for (char c : array){
							identify += c;
						}
						String errorStr = ""+strLine+"行:  字符串"+identify+"没有正确结束,缺少\'";
						errorList.add(errorStr);
					}
				}
			String identify ="";
			for (char c : array){
				identify += c;
			}
			tokenList.add(new TokenTable(3 , identify));
			break;
			}
		}
	}
	
	public void OperationAnalyse(int ASCII , BufferedReader inputFile) throws IOException {
		token[2].analyse(""+(char)ASCII, tokenList, errorList, textLine);
	}
	
	public void AddToFile(int fileNO) throws IOException {
		String[] arrayFileName = new String[2];
		arrayFileName = allFiles[fileNO-1].split("\\.") ;
		String fileName = arrayFileName[0]+"Table."+arrayFileName[1];
		File tableFile = new File ("accidenceAnalyse\\accidenceAnalyseTable" , ""+fileName) ;
		if(tableFile.exists()){
			tableFile.delete();
			tableFile.createNewFile();
		}
		else
			tableFile.createNewFile();
		
	//	DataOutputStream out = new DataOutputStream(new FileOutputStream("accidenceAnalyse\\accidenceAnalyseTable\\"+fileName));
		for (TokenAnalyse t : token){
			t.getArrayList(arrayFileName[0]);
		}
	}
	
	public static void main(String[] args) throws IOException
	{
		// 目录列表模块:
		int fileNO = TT.DirectryList();
		if (fileNO == 10000)
			return;
		// 开始词法分析:
		TT.BeginAnalyse(fileNO);
		// 输出Token表
		TT.printTokenTable();
		TT.AddToFile(fileNO);
		TT.printError();
	}
	
//:  内部数据定义:
	final static Text TT = new Text();
	private static ArrayList<TokenTable> tokenList = new ArrayList<TokenTable>();    //  token表存储在这里!
	private static ArrayList<String> errorList = new ArrayList<String>();    //  错误语句数组!
	private static int textLine = 1;
	private String[] allFiles;     // 存储搜索到的源文件
	private String fileNameStr = ".+\\.txt";   // 源文件的正则表达式:  必须要以 .txt 的格式存放
	private TokenAnalyse[] token = {new IdentifierAnalyse() , new ConstAnalyse() , new OperationAnalyse()};
}











⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -