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

📄 compiler.java

📁 上海复旦大学计算机系学子写的JAVA版本编译原理词法、语法分析程序(LR0)
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.*;
import java.util.*;

public class Compiler extends Frame implements ActionListener{
	int row = 1;//数排列,横坐标
	int line = 1;//横排行,竖坐标。当遇到回车换行的时候,line++,row = 0;
	boolean lexical_checked = false;
	ArrayList styleStr = new ArrayList();//tokens的类型
	ArrayList programStr = new ArrayList();//程序的各个实际标志符
	
	ArrayList styleStack = new ArrayList();//符号栈
	ArrayList stateStack = new ArrayList();//状态栈,符号栈与状态栈同时变化,长度始终相同。
	
	MenuBar mb = new MenuBar();
	Menu fileMenu = new Menu("File");
	Menu actionMenu = new Menu("Project");
	MenuItem closeWindow = new MenuItem("Exit");
	MenuItem openFile = new MenuItem("Open file");
	MenuItem lexical_check = new MenuItem("Check Lex");
	MenuItem syntax_check = new MenuItem("Check Syntax");
	
	int begin = 0;//当读到第一个字母的时候,标志其位置
	int end = 0;
	int num_begin = 0;//标志数字首位开始标志
	int num_end = 0;//标志数字末尾表示标志
	TextArea text = new TextArea(25,60);
	TextArea error_text = new TextArea(10,60);

	FileDialog file_dialog_load = new FileDialog(this, "Open file...", FileDialog.LOAD);
	
	Compiler(){
		
		this.setLayout(new FlowLayout());
		
		this.setMenuBar(mb);
		mb.add(fileMenu);
		mb.add(actionMenu);
		
		fileMenu.add(openFile);
		fileMenu.add(closeWindow);
		
		actionMenu.add(lexical_check);
		actionMenu.add(syntax_check);
		
		this.add(text);
		this.add(error_text);
		error_text.setText("Lexical Information: \n");
		
		closeWindow.addActionListener(this);
		openFile.addActionListener(this);
		lexical_check.addActionListener(this);
		syntax_check.addActionListener(this);
		this.setSize(500, 600);
		this.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		this.setVisible(true);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Compiler compiler = new Compiler();
	}
	
	public void actionPerformed(ActionEvent e){
		if(e.getSource() == closeWindow){
			System.exit(0);
		}else if(e.getSource() == openFile){
			file_dialog_load.setVisible(true);
			File myfile = new File(file_dialog_load.getDirectory(), file_dialog_load.getFile());
			try{
				BufferedReader bufReader = new BufferedReader(new FileReader(myfile));
				String content = "";
				String str;
				while((str = bufReader.readLine()) != null){
					content += str + "\n";
					text.setText(content);
				}
			}catch(IOException ie){
				error_text.appendText("IOexception occurs...");
			}
		}else if(e.getSource() == lexical_check){
			//error_text.setText("Lexical Information: \n");
			error_text.setText("");
			row = 0;
			line = 1;
			checkLexical();
			lexical_checked = true;
		}else if(e.getSource() == syntax_check){
			if(lexical_checked  == false){
				error_text.appendText("You have not checked the lexical! \n");
			}else{
				check_syntax();				
			}
		}
	}
	/*
	 * 对Text区域数据区进行词法检测
	 * */
	public void checkLexical(){
		/***********************************/
		styleStr.clear();
		programStr.clear();
		styleStack.clear();
		stateStack.clear();
		/***********************************/
		String error_info = error_text.getText();
		String content = text.getText(); 
		if(content.equals("")){
			error_info += "Text is empty! You havn't input any code!\n";
			error_text.setText(error_info);
		}
		else{
			int i = 0;//选择第i个字符进行检测。
			int N = content.length();
			int state = 0;//状态标志
			for(i = 0; i < N; i++){//对所有字符进行检测
				row++;
				char c = content.charAt(i);			
				switch(state){
					case 0:
						//row++;
						if(c == ',' || c == ' ' || c == '\t' || c == '{' || c =='}' || c == '(' || c == ')' || c == ';' || c == '[' || c == ']') {
							if(isDigit(content.charAt(i - 1)) && isDigit(content.charAt(begin))){
								end = i;
								error_text.append("info: 数值表达式 " + content.substring(begin, end) + '\n');
							}
							/******new*****/
							if(c == ',' || c == '{' ||c == '}'||c == '(' ||c == ')'|| c == ';'){
								String str = "" + c;
								programStr.add(str);
								styleStr.add(str);
							}	
							state = 0;
						}
						else if(c == '+') state = 1;
						else if(c == '-') state = 2;
						else if(c == '*') state = 3;
						else if(c == '/') state = 4;
						else if(c == '!') state = 5;
						else if(c == '>') state = 6;
						else if(c == '<') state = 7;
						else if(c == '=') state = 8;
						else if(c == '\n') state = 9;//输入为回车
						else if(isLetter(c)) {
							state = 10;
							begin = i;
						}
						else if(isDigit(c)) {
							begin = i;
							state = 11;
						}
						else if(c == '#') state = 12;
						else if(c == '&') state = 14;
						else if(c == '|') state = 15;
						else if(c == '"') state = 16;
						else error_text.appendText("line: " + line + " row: " + row + " error: '" + c + "' Undefined character! \n");
						break;
					case 1://标志符是 +
						//row++;
						if(c == '+'){
							state = 0;				
							error_text.appendText("info: 运算符 '++'\n");
							/***new**/
							programStr.add("++");
							styleStr.add("++");
						}
						else if(c == '='){
							state = 0;
							error_text.appendText("info: 运算符 '+='\n");
							/***new**/
							programStr.add("+=");
							styleStr.add("+=");
														
						}else{
							state = 0;
							error_text.appendText("info: 运算符 '+'\n");
							/***new**/
							programStr.add("+");
							styleStr.add("+");
							i--;
							row--;
						}
						break;
					case 2://标志符是 -
						if(c == '-'){
							error_text.appendText("info: 运算符 '--'\n");
							/***new**/
							programStr.add("--");
							
						//	styleStr.add("--")
						}
						else if(c == '=') {
							error_text.appendText("info: 运算符 '-='\n");
							/***new**/
							programStr.add("=");
							styleStr.add("=");
						}
						else{
							error_text.appendText("info: 运算符 '-'\n");
							/***new**/
							programStr.add("-");
							styleStr.add("-");
							i--;
							row--;
						}
						state = 0;
						break;
					case 3://标志符是 *
						if(c == '='){
							error_text.appendText("info: 运算符 '*='\n");
							/***new**/
							programStr.add("*=");
							styleStr.add("*=");
						}
						else{
							error_text.appendText("info: 运算符 '*'\n");
							/***new**/
							programStr.add("*");
							styleStr.add("*");
							i--;
							row--;
						}
						state = 0;
						break;
					case 4://标志符是 /
						if(c == '/'){
							while((c) != '\n'){
								c = content.charAt(i);
								i++;
							}
							state = 0;
							error_text.appendText("info: 注释部分 // \n");
						}else if(c == '='){
							state = 0;
							error_text.appendText("info: 运算符 /= \n");
							/***new**/
							programStr.add("/=");
							styleStr.add("/=");
						}else{
							state = 0;
							error_text.appendText("info: 运算符 / \n");
							/***new**/
							programStr.add("/");
							styleStr.add("/");
							
							i--;
							row--;
						}
						//state = 0;
						break;
					case 5://标志符是 !
						if(c == '='){
							error_text.appendText("info: 运算符 != \n");
							/***new**/
							programStr.add("!=");
							styleStr.add("!=");
							state = 0;
						}else{
							state = 0;
							i--;
							row--;
							error_text.appendText("info: 运算符 ! \n");
							/***new**/
							programStr.add("!");
							styleStr.add("!");
						}
						//state = 0;
						break;
					case 6://标志符是 >
						if(c == '='){
							error_text.appendText("info: 运算符 >= \n");
							/***new**/
							programStr.add(">=");
							styleStr.add(">=");
							state = 0;
						}else{
							i--;
							state = 0;
							error_text.appendText("info: 元算符 > \n");
							/***new**/
							programStr.add(">");
							styleStr.add(">");
						}
						//state = 0;
						break;
					case 7://标志符是 <
						if(c == '='){
							error_text.appendText("info: 运算符 <= \n");
							/***new**/
							programStr.add("<=");
							styleStr.add("<=");
							state = 0;
						}else{
							i--;
							state = 0;
							error_text.appendText("info: 运算符 < \n");
							/***new**/
							programStr.add("<");
							styleStr.add("<");
						}
						break;
					case 8://标志符是 =
						if(c == '='){
							error_text.appendText("info: 运算符 == \n");
							/***new**/
							programStr.add("==");
							styleStr.add("==");
							state = 0;
						}else{
							state = 0;
							error_text.appendText("info: 运算符 = \n");
							/***new**/
							programStr.add("=");
							styleStr.add("=");
						}
						break;
					case 9://标志符是 回车
						state = 0;
						row = 1;
						line ++;
						i--;//诡异啊!这里竟然要减一才能正常的忽略回车!
						break;
					case 10://标志符是 字母
						if(isLetter(c) || isDigit(c)){
							state = 10;
						}else{
							end = i;
							String id = content.substring(begin, end);
							if(isKey(id)){
								error_text.appendText("info: 关键字 " + id + '\n');
								if(id.equals("if")||id.equals("else")||id.equals("for")||id.equals("while")||id.equals("do")||id.equals("repeat")||id.equals("until")
										||id.equals("read")||id.equals("write")||id.equals("return")||id.equals("to")){
									styleStr.add(id);
								}else if(id.equals("int")||id.equals("real")||id.equals("boolean")){
									styleStr.add("type");
								}else
									styleStr.add("C");
							}
							else{
								error_text.appendText("info: 标志符 " + id + '\n');
								styleStr.add("C");
							}
							/***new**/
							programStr.add(id);
							
							i--;
							row--;
							state = 0;
						}
						//state = 0;
						break;
					case 11://标志符是 数字
						if(c == 'e' || c == 'E')
							state = 13;
						else if(isDigit(c) || c == '.'){
							//省略跳过,i加一操作
						}else {
							if(isLetter(c)){
								error_text.appendText("error: line " + line + " row " + row + " 数字格式错误或者标志符错误\n");
							}
							end = i;
							String id = content.substring(begin, end);
							/***new**/
							programStr.add(id);
							styleStr.add("K");
							//i--;

⌨️ 快捷键说明

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