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

📄 analyzer.java

📁 一种CMM语言的词法分析
💻 JAVA
字号:
/*
*  吕渊 200532580144
*  使用工具:eclipse
*  Java SE 6
*/
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.*;

public class Analyzer extends JApplet {
	//图标
	ImageIcon openIcon = new ImageIcon("Icon/Open.png"),
		saveIcon = new ImageIcon("Icon/Save.png"),
		undoIcon = new ImageIcon("Icon/Undo.png"),
		redoIcon = new ImageIcon("Icon/Redo.png"),
		colorIcon = new ImageIcon("Icon/Color.png"),
		deleteAllIcon = new ImageIcon("Icon/Delete.png"),
		lexicalIcon = new ImageIcon("Icon/Lexical.png"),
		syntaxIcon = new ImageIcon("Icon/Syntax.png");
	
	//菜单项
	private JMenuItem jmiOpen = new JMenuItem("打开文件", openIcon);
	private JMenuItem jmiSaveInput = new JMenuItem("输入内容另存为...", saveIcon);
	private JMenuItem jmiSaveResult = new JMenuItem("分析结果另存为...", saveIcon);
	private JMenuItem jmiExit = new JMenuItem("退出");
	private JMenuItem jmiUndo = new JMenuItem("撤消", undoIcon);
	private JMenuItem jmiRedo = new JMenuItem("重复", redoIcon);
	private JMenuItem jmiForeground = new JMenuItem("前景色", colorIcon);
	private JMenuItem jmiBackground = new JMenuItem("背景色", colorIcon);
	protected JMenuItem lexicalAnalyzer = new JMenuItem("词法分析", lexicalIcon);
	protected JMenuItem syntaxAnalyzer= new JMenuItem("语法分析", syntaxIcon);
	protected JMenuItem jMenuClean = new JMenuItem("清空", deleteAllIcon);
	protected JMenu jMenuExe = new JMenu("运行(D)");//菜单项
	protected JMenuBar jMenuBar = new JMenuBar();//菜单
	
	private JLabel jlblStatus = new JLabel();//信息栏
	private JFileChooser jFileChooser = new JFileChooser(new File("."));//文件对话框
	private JTextArea lineNoArea = new JTextArea();//显示行号
	protected JTextArea jta = new JTextArea();//输入区域
	protected DefaultListModel listModel = new DefaultListModel();
	protected JList jlst = new JList(listModel);//输出区域
	JSplitPane center = new JSplitPane();//中央区域
	
	public ArrayList<Integer> tokenStart = new ArrayList<Integer>();//对应输出位置
	public ArrayList<Integer> tokenEnd = new ArrayList<Integer>();//对应输出位置
	boolean change = true;//输入文本改变
	int clickCount = 1;//双击JList次数
	
	LinkedList<String> buffer = new LinkedList<String>();//输入内容缓冲
	final int maxSize = 100;//缓冲存储上限
	int index = 0;//当前显示内容在缓冲中的索引
	boolean flag = false;//是否使用快捷键控制索引显示
	
	public Analyzer() {
		buffer.add("");
		
		//菜单
		JMenu jMenuFile = new JMenu("文件(F)");
		jMenuFile.setMnemonic('F');
		jMenuFile.add(jmiOpen);
		jMenuFile.addSeparator();
		jMenuFile.add(jmiSaveInput);
		jMenuFile.add(jmiSaveResult);
		jMenuFile.addSeparator();
		jMenuFile.add(jmiExit);

		JMenu jMenuEdit = new JMenu("编辑(E)");
		jMenuEdit.setMnemonic('E');
		jMenuEdit.add(jmiUndo);
		jMenuEdit.add(jmiRedo);
		
		JMenu jMenuShow = new JMenu("显示(S)");
		jMenuShow.setMnemonic('S');
		jMenuShow.add(jmiForeground);
		jMenuShow.add(jmiBackground);
		
		jMenuExe.setMnemonic('D');
		jMenuExe.add(lexicalAnalyzer);
		jMenuExe.addSeparator();
		jMenuExe.add(syntaxAnalyzer);
		jMenuExe.addSeparator();
		jMenuExe.add(jMenuClean);
		
		jMenuBar.add(jMenuFile);
		jMenuBar.add(jMenuEdit);
		jMenuBar.add(jMenuShow);
		jMenuBar.add(jMenuExe);

		setJMenuBar(jMenuBar);
		
		//输入文本区及行号显示区域属性及滚动
		jta.setEditable(true);
		jta.setFont(new Font(Font.SERIF, Font.PLAIN, 15));
		jta.setForeground(Color.BLUE);
		jta.setTabSize(1);
		lineNoArea.setFont(new Font(Font.SERIF, Font.PLAIN, 15));
		lineNoArea.setEditable(false);
		lineNoArea.setText("1");
		lineNoArea.setBackground(Color.LIGHT_GRAY);
		JPanel jplInput = new JPanel(new BorderLayout());
		jplInput.add(lineNoArea, BorderLayout.WEST);
		jplInput.add(jta, BorderLayout.CENTER);
		JScrollPane inputScrollPane = new JScrollPane(jplInput);
		inputScrollPane.setBorder(new TitledBorder("   请输入   "));
		
		//JList输出区域及滚动
		jlst.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		jlst.setFocusable(false);
		JScrollPane outputScrollPane = new JScrollPane(jlst);
		outputScrollPane.setBorder(new TitledBorder("   分析结果   "));
		
		JPanel jplRight = new JPanel(new GridLayout(2,1));
		jplRight.add(inputScrollPane);
		jplRight.add(outputScrollPane);
		
		center = new JSplitPane(1, 
				new JScrollPane(new JTree(new DefaultMutableTreeNode("Syntax Tree"))), jplRight);
		center.setContinuousLayout(true);
		center.setOneTouchExpandable(true);
		
		//添加信息栏及中央区域
		getContentPane().add(jlblStatus, BorderLayout.SOUTH);
		getContentPane().add(center, BorderLayout.CENTER);
		
		
		//操作快捷键
		lexicalAnalyzer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ActionEvent.ALT_MASK));
		jmiOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
		jMenuClean.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1, ActionEvent.CTRL_MASK));
		syntaxAnalyzer.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ActionEvent.CTRL_MASK));
		jmiUndo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, ActionEvent.CTRL_MASK));
		jmiRedo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, ActionEvent.CTRL_MASK));
		
		//以下为监听器注册及实现
		/** 输入文本区内容变化响应事件*/
		jta.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {}
			/** 删除操作*/
			public void removeUpdate(DocumentEvent e) {
				clickCount = 0;
				change = true;
				showLineNo();//显示行号
				if (flag == false) {
					if (index < buffer.size()-1) 
						buffer = new LinkedList<String>(buffer.subList(0, index+1));
					buffer.add(jta.getText());
					if (buffer.size() > maxSize) buffer.removeFirst();
					else index++;
				}
			}
			/** 输入操作*/
			public void insertUpdate(DocumentEvent e) {
				clickCount = 0;
				change = true;
				showLineNo();//显示行号
				if (flag == false) {
					if (index < buffer.size()-1) 
						buffer = new LinkedList<String>(buffer.subList(0, index+1));
					buffer.add(jta.getText());
					if (buffer.size() > maxSize) buffer.removeFirst();
					else index++;
				}
			}
		});
		

		/** 对JList进行双击的响应事件*/
		jlst.addMouseListener(new MouseAdapter() {
		    public void mouseClicked(MouseEvent e) {
				if (!change) { 
					try {
						int select = jlst.getSelectedIndex();
						int start = tokenStart.get(select);
						int end = tokenEnd.get(select);
						if (start >=0 ) jta.select(start, end);
						else if (start == -2) {
							int endT = tokenStart.size();
							for (int i = select+1; i < endT; i++)
								if (tokenStart.get(i) == -2) {
									endT = i;
									break;
								}
							clickCount++;
							if (clickCount == endT - select) clickCount = 1;
							start = tokenStart.get(select + clickCount);
							end = tokenEnd.get(select + clickCount);
							if (start != -3) jta.select(start, end);
						}
					}
					catch (Exception ex) {}
				}
		     }
		});
		
		/** JList改变选中的响应事件*/
		jlst.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent lse) {
				clickCount =0;
			}
		});
		
		/** 读入文件*/
		jmiOpen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				open();
				showLineNo();
			}
		});
		
		/** 保存输入*/
		jmiSaveInput.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				save(1);
			}
		});
		
		/** 保存结果*/
		jmiSaveResult.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				save(2);
			}
		});

		/** 结束程序*/
		jmiExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				System.exit(0);
			}
		});
		
		/** 撤消输入*/
		jmiUndo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				if (index > 0) {
					flag = true;
					index--;
					jta.setText(buffer.get(index));
					flag = false;
				}
			}
		});
		
		/** 重复输入*/
		jmiRedo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				if (index < buffer.size()-1) {
					flag = true;
					index++;
					jta.setText(buffer.get(index));
					flag = false;
				}
			}
		});
		
		/** 设置前景色*/
		jmiForeground.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				Color selectedColor =
					JColorChooser.showDialog(null, "选择前景色",
							jta.getForeground());

				if (selectedColor != null)
					jta.setForeground(selectedColor);
			}
		});

		/** 设置背景色*/
		jmiBackground.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				Color selectedColor =
					JColorChooser.showDialog(null, "选择背景色",
							jta.getForeground());

				if (selectedColor != null)
					jta.setBackground(selectedColor);
			}
		});
		
		/** 词法分析*/
		lexicalAnalyzer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				center.setLeftComponent(new JScrollPane(
						new JTree(new DefaultMutableTreeNode("Syntax Tree"))));
				
				LexicalAnalyze lexical = new LexicalAnalyze(jta.getText());
				if (lexical.toArrayList().isEmpty()) 
					JOptionPane.showMessageDialog (null, "请输入!", 
							"Notice", JOptionPane.INFORMATION_MESSAGE);
				else {
					tokenStart = lexical.tokenStart;
					tokenEnd = lexical.tokenEnd;
					listModel.clear();
					for(String value: lexical.toArrayList())
						listModel.addElement(value);
					change = false;
				}
			}
		});
		
		/** 语法分析*/
		syntaxAnalyzer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (jta.getText().trim().equals("")){
					JOptionPane.showMessageDialog (null, "请输入!", 
							"Notice", JOptionPane.INFORMATION_MESSAGE);
				}
				else {
					SyntaxAnalyze syntax = new SyntaxAnalyze(jta.getText());
					listModel.clear();
					center.setLeftComponent(new JScrollPane(
							new JTree(new DefaultMutableTreeNode("Syntax Tree"))));
					for(String value: syntax.toArrayList())
						listModel.addElement(value);
					change = false;
					if (syntax.lexicalError == true) {
						JOptionPane.showMessageDialog (null, "词法分析发现错误!", 
								"Notice", JOptionPane.INFORMATION_MESSAGE);
						tokenStart = syntax.tokenStart;
						tokenEnd = syntax.tokenEnd;
					}
					else if (syntax.syntaxError == true) {
						JOptionPane.showMessageDialog (null, "含有语法错误!", 
								"Notice", JOptionPane.INFORMATION_MESSAGE);
						tokenStart = syntax.tokenErrorStart;
						tokenEnd = syntax.tokenErrorEnd;
					}
					else {
						center.setLeftComponent(new JScrollPane(
								new JTree(new DefaultTreeModel(syntax.syntaxTree))));
						tokenStart = syntax.tokenRightStart;
						tokenEnd = syntax.tokenRightEnd;
					}
				}
			}
		});
		
		/** 清空*/
		jMenuClean.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				change = true;
				lineNoArea.setText("1");
				jta.setText(null);
				center.setLeftComponent(new JScrollPane(
						new JTree(new DefaultMutableTreeNode("Syntax Tree"))));
			}
		});
	}
	
	/** 显示行号*/
	private void showLineNo() {
		String lineNo = "";
		for (int i = 1; i <= jta.getLineCount(); i++)
			if (i == 1)lineNo += "" + 1;
			else lineNo += "\n" + i;
		lineNoArea.setText(lineNo);
	}
	
	/** 打开文件*/
	private void open() {
		if (jFileChooser.showOpenDialog(this) ==
			JFileChooser.APPROVE_OPTION)
			open(jFileChooser.getSelectedFile());
	}
	
	private void open(File file) {
		try {
			jta.setText(null);
			BufferedReader input = new BufferedReader(
					new FileReader(file));
			String line;
			while ((line = input.readLine()) != null) {
				jta.append(line + "\n");
			}
			jta.setText(jta.getText().trim());
			input.close();

			jlblStatus.setText(file.getName() + " 已打开");
		}
		catch (IOException ex) {
			jlblStatus.setText(file.getName() + " 打开失败!");
		}
	}

	/** 保存*/
	private void save(int x) {
		if (jFileChooser.showSaveDialog(this) ==
			JFileChooser.APPROVE_OPTION) {
			save(jFileChooser.getSelectedFile(), x);
		}
	}
	
	private void save(File file, int x) {
		try {
			BufferedWriter output =
			      new BufferedWriter(new FileWriter(file));
			if (x == 1) output.write(jta.getText());
			else {
				String result = "";
				for(int i = 0; i < jlst.getModel().getSize(); i++) 
					result += jlst.getModel().getElementAt(i) + "\n";
				output.write(result);
			}
			output.close();

			jlblStatus.setText(file.getName()  + " 已保存 ");
		}
		catch (IOException ex) {
			jlblStatus.setText(file.getName()  + " 保存失败! ");
		}
	}
	
	public static void main(String[] args) {
		Analyzer applet = new Analyzer();
		
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(3);
		frame.setTitle("CMM Analyzer Beta4");
		frame.getContentPane().add(applet, BorderLayout.CENTER);
		applet.init();
		applet.start();
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		frame.setSize(d.width*4/5,d.height*4/5);
		frame.setLocation(d.width / 10, d.height / 10);
		frame.setVisible(true);
	}
}

⌨️ 快捷键说明

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