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

📄 cffx.java

📁 自己写的编译原理作业
💻 JAVA
字号:
package edu.psl.by.cffx;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Vector;

public class Cffx {
	String sourceCode = "";
	ArrayList<String> keyWords = new ArrayList<String>();// 关键词集合
	ArrayList<String> limitWords = new ArrayList<String>();// 限界符集合
	ArrayList<String> contents = new ArrayList<String>();// 源代码单词分解
	Map<String, Integer> key;// 源代码找出的关键词,以及所在行数
	ArrayList<Glorb> glorb = new ArrayList<Glorb>();// 源代码中的全局变量,以及所在行数
	ArrayList<Local> local = new ArrayList<Local>();// 源代码中的局部变量,以及所在
	ArrayList<String> ConstList = new ArrayList<String>();// 常量表
	ArrayList<String> IdentifierList = new ArrayList<String>();// 标识符表
	ArrayList<String> OutputList = new ArrayList<String>();// 输出表
	ArrayList<String> lines = new ArrayList<String>();// 每行的字符
	int big = 0;
	int line = 1;
	String functionName = null;

	/**
	 * 初始化关键词表和限界符运算符表
	 */
	public Cffx() {
		String keys[] = { "auto", "double", "int", "struct", "break", "else",
				"long", "switch", "case", "enum", "register", "typedef",
				"char", "extern", "return", "union", "const", "float", "short",
				"unsigned", "continue", "for", "signed", "void", "default",
				"goto", "sizeof", "volatile", "do", "while", "static", "if" };
		for (int i = 0; i != keys.length; i++) {
			keyWords.add(keys[i]);
		}
		/* 运算、限界符 */
		String[] limit = new String[] { " ", "(", ")", "[", "]", "->", ".",
				"!", "++", "--", "&", "~", "*", "/", "%", "+", "-", "<<", ">>",
				"<", "<=", ">", ">=", "==", "!=", "&&", "||", "=", "+=", "-=",
				"*=", "/=", ",", ";", "{", "}", "#", "_", "'" };
		for (int i = 0; i != limit.length; i++) {
			limitWords.add(limit[i]);
		}
	}

	/***************************************************************************
	 * 十进制转二进制函数
	 **************************************************************************/
	private String dtb(String buf) {
		int[] temp = new int[20];
		String binary = "";
		int val = 0, i = 0;

		/* 先将字符转化为十进制数 */

		val = Integer.parseInt(buf);

		if (val == 0) {
			return (Integer.toString(val));
		}

		i = 0;
		while (val != 0) {
			temp[i++] = val % 2;
			val /= 2;
		}

		binary = "";
		for (int j = 0; j <= i - 1; j++)
			binary += (char) (temp[i - j - 1] + 48);

		return (binary);
	}

	/***************************************************************************
	 * 根据不同命令查表或造表函数
	 **************************************************************************/
	private int find(String buf, int type, int command) {
		int number = 0;
		String temp;

		Iterator ie = null;
		ArrayList<String> al = null;
		switch (type) {
		case 1:// 关键字表
			ie = keyWords.iterator();
			break;
		case 2:// 标识符表
			ie = this.IdentifierList.iterator();
			break;
		case 3:// 常数表
			ie = this.ConstList.iterator();
			break;
		case 4:// 运算、限界符表
			ie = limitWords.iterator();
			break;
		}

		if (ie != null)
			while (ie.hasNext()) {
				temp = ie.next().toString();
				if (temp.equalsIgnoreCase(buf)) {
					return number;
				}
				number++;
			}

		if (command == 1) {
			/* 找不到,当只需查表,返回0,否则还需造表 */
			return 0;
		}

		switch (type) {
		case 1:
			al = this.keyWords;
			break;
		case 2:
			al = this.IdentifierList;
			break;
		case 3:
			al = this.ConstList;
			break;
		case 4:
			al = this.limitWords;
			break;
		}
		if (al != null)
			al.add(buf);

		return number + 1;
	}

	/***************************************************************************
	 * 数字串处理函数
	 **************************************************************************/
	private void cs_manage(String buffer) {
		String binary = dtb(buffer);
		int result = find(binary, 3, 2);
		this.OutputList.add(String.format("%1$s\t\t\t数字\t\t\t%2$s", buffer,
				result));
	}

	private String getFunctionName(int lineno) {
		String buffer = lines.get(lineno - 2);
		Site t = new Site();
		char ch;
		char[] array = new char[100];

		while (t.getLoc() < buffer.length() - 1) {
			int i = 0;
			ch = getchc(t);
			String word;
			if (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'))
					|| (ch == '_')) {
				while (((ch >= 'A') && (ch <= 'Z'))
						|| ((ch >= 'a') && (ch <= 'z')) || (ch == '_')
						|| ((ch >= '0') && (ch <= '9'))) {
					array[i++] = ch;
					ch = getchc(t);
				}
				array[i++] = '\0';
				word = joinString(array, array.length);
				int result = find(word, 1, 1);

				if (result != 0) {

				} else {
					return word;
				}
				if (t.getLoc() < buffer.length())
					t.dec();
			} else if ((ch == ' ') || (ch == '\t') || (ch == '\r'))
				/* 消除空格符和水平制表符 */
				;
		}
		return null;
	}

	/***************************************************************************
	 * 字符串处理函数
	 **************************************************************************/
	private void ch_manage(String buffer) {
		int result = find(buffer, 1, 1);

		if (result != 0) {
			this.OutputList.add(String.format("%1$s\t\t\t关键字\t\t\t%2$s",
					buffer, result));

		} else {
			result = find(buffer, 2, 2);
			this.OutputList.add(String.format("%1$s\t\t\t标识符\t\t\t%2$s",
					buffer, result));
			if (big == 1) {
				Glorb temp = new Glorb(buffer, line);
				glorb.add(temp);
			} else if (big > 1 && functionName != null) {
				Local l = new Local();
				l.setFuncionName(functionName);
				l.setLine(line);
				l.setName(buffer);
				local.add(l);
			}
		}
	}

	/***************************************************************************
	 * 出错处理函数
	 **************************************************************************/
	private void er_manage(String error, int lineno) {
		this.OutputList.add(String.format("错误标识符: %1$s,所在行: %2$s", error,
				lineno));
	}

	/***************************************************************************
	 * 转换Char数组为string
	 **************************************************************************/
	private String joinString(char[] array, int Length) {
		String s = "";
		if (array.length > 0)
			for (int i = 0; i < Length; i++) {
				if (array[i] != '\0') {
					s += array[i];
				} else {
					break;
				}
			}
		return s;
	}

	private char getchc(Site n) {
		char[] c = sourceCode.toCharArray();
		if (n.getLoc() < c.length) {
			char r = c[n.getLoc()];
			n.inc();
			return r;
		}
		return sourceCode.charAt(sourceCode.length() - 1);
	}

	/***************************************************************************
	 * 扫描程序
	 * 
	 * @throws FileNotFoundException
	 **************************************************************************/
	public void Parse(String fileName) throws FileNotFoundException {
		FileInputStream fis = new FileInputStream(fileName);
		byte[] buff = new byte[500];
		int len;

		try {
			len = fis.read(buff);
			sourceCode = new String(buff, 0, len);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		char[] lineContent = new char[100];
		int k = 0;
		char ch;
		int i = 0;
		int count, result, errorno = 0;
		char[] array = new char[30];
		String word = "";

		/* 按字符依次扫描源程序,直至结束 */
		Site n = new Site();
		while (n.getLoc() < sourceCode.length() - 1) {
			i = 0;
			ch = getchc(n);
			lineContent[k++] = ch;
			/* 以字母开头 */
			if (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'))
					|| (ch == '_')) {
				while (((ch >= 'A') && (ch <= 'Z'))
						|| ((ch >= 'a') && (ch <= 'z')) || (ch == '_')
						|| ((ch >= '0') && (ch <= '9'))) {
					array[i++] = ch;
					ch = getchc(n);
				}
				array[i++] = '\0';
				word = joinString(array, array.length);
				ch_manage(word);
				if (n.getLoc() < sourceCode.length())
					n.dec();
			} else if (ch >= '0' && ch <= '9') {
				/* 以数字开头 */
				while (ch >= '0' && ch <= '9') {
					array[i++] = ch;
					ch = getchc(n);
					if (((ch >= 'A') && (ch <= 'Z'))
							|| ((ch >= 'a') && (ch <= 'z')) || (ch == '_')) {
						while (((ch >= 'A') && (ch <= 'Z'))
								|| ((ch >= 'a') && (ch <= 'z')) || (ch == '_')
								|| ((ch >= '0') && (ch <= '9'))) {
							array[i++] = ch;
							ch = getchc(n);
							word = joinString(array, array.length);
							er_manage(word, line);
							errorno++;
						}
					} else {
						while (ch >= '0' && ch <= '9') {
							array[i++] = ch;
							ch = getchc(n);

						}
						array[i++] = '\0';
						word = joinString(array, array.length);
						cs_manage(word);
					}
					if (n.getLoc() < sourceCode.length())
						n.dec();

				}

			} else if ((ch == ' ') || (ch == '\t') || (ch == '\r'))
				/* 消除空格符和水平制表符 */
				;
			else if (ch == '\n') {
				/* 消除回车并记录行数 */
				String temp;
				lineContent[k++] = '\0';
				temp = joinString(array, array.length);
				line++;
				lines.add(temp);
				k = 0;
				lineContent = new char[100];
			} else if (ch == '/') {
				/* 消除注释 */
				ch = getchc(n);
				if (ch == '=') {
					/* 判断是否为‘/=’符号 */
					this.OutputList.add(String
							.format("/=\t\t\t运算符或界限符\t\t\t32"));
				} else if (ch != '*') {
					/* 若为除号,写入输出 */
					this.OutputList
							.add(String.format("/\t\t\t运算符或界限符\t\t\t13"));
					n.dec();
				} else if (ch == '*') {
					/* 若为注释的开始,消除包含在里面的所有字符 */
					count = 0;
					ch = getchc(n);
					while (count != 2) {
						/* 当扫描到‘*’且紧接着下一个字符为‘/’才是注释的结束 */
						count = 0;
						while (ch != '*')
							ch = getchc(n);
						count++;
						ch = getchc(n);
						if (ch == '/')
							count++;
						else
							ch = getchc(n);
					}
				}
			} else if (ch == '"') {
				/* 消除包含在双引号中的字符串常量 */
				this.OutputList.add(String.format("%1$s\t\t\t运算符或界限符\t\t\t37",
						ch));
				while (ch != '"')
					ch = getchc(n);
				this.OutputList.add(String.format("%1$s\t\t\t运算符或界限符\t\t\t37",
						ch));
			} else {
				/* 首字符为其它字符,即运算限界符或非法字符 */
				array[0] = ch;
				/* 再读入下一个字符,判断是否为双字符运算、限界符 */
				ch = getchc(n);
				/* 若该字符非结束符 */
				if (n.getLoc() < sourceCode.length()) {
					array[1] = ch;
					array[2] = '\0';
					word = joinString(array, 2);
					result = find(word, 4, 1); /* 先检索是否为双字符运算、限界符 */
					if (result == 0) {
						/* 若不是 */
						array[2] = '\0';
						word = joinString(array, 1);
						result = find(word, 4, 1);
						/* 检索是否为单字符运算、限界符 */
						if (result == 0) {
							/* 若还不是,则为非法字符 */
							er_manage(word, line);
							errorno++;
							n.dec();
						} else {
							/* 若为单字符运算、限界符,写入输出并将扫描指针回退一个字符 */
							this.OutputList.add(String.format(
									"%1$s\t\t\t运算符或界限符\t\t\t%2$s\t", word,
									result));
							if (word.equals("{")) {
								big++;
								if (big > 1) {
									functionName = getFunctionName(line);
								}
							}
							if (word.equals("}")) {
								big--;
							}
							n.dec();
						}
					} else {
						/* 若为双字符运算、限界符,写输出 */
						this.OutputList.add(String.format(
								"%1$s\t\t\t运算符或界限符\t\t\t%2$s", word, result));
					}
				} else {
					/* 若读入的下一个字符为结束符 */
					array[2] = '\0';
					word = joinString(array, 1);
					/* 只考虑是否为单字符运算、限界符 */
					result = find(word, 4, 1);
					/* 若不是,转出错处理 */
					if (result == 0)
						er_manage(word, line);
					else {
						/* 若是,写输出 */
						this.OutputList.add(String.format(
								"%1$s\t\t\t运算符或界限符\t\t\t%2$s", word, result));
					}
				}
			}
		}
		/* 报告错误字符个数 */
		this.OutputList.add(String.format("\n共有 %1$d个错误.\n", errorno));
		for (i = 0; i != OutputList.size(); i++) {
			System.out.println(OutputList.get(i));
		}
		System.out.println("全局变量:");
		for (i = 0; i != glorb.size(); i++) {
			System.out.println(glorb.get(i).getContent() + "   "
					+ glorb.get(i).getLine());
		}
		System.out.println("局部变量:");
		for (i = 0; i != local.size(); i++) {
			System.out.println(local.get(i).getName() + "   "
					+ local.get(i).getFuncionName()+"   "+local.get(i).getLine());
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String fileName = sc.nextLine();
		Cffx cffx = new Cffx();
		try {
			cffx.Parse(fileName);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

⌨️ 快捷键说明

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