简单实现词法分析器

说明

  • 开发语言: java
  • 界面设计:采用eclipse的插件windowbuilder
  • 功能描述:统计行数和列数用于错误单词的定位,如果发现错误则报告出错。删除空格类字符,包括回车、制表符空格,按拼写单词(关键字、标识符、常数、运算符、关系运算符、分界符号),并用(内码,属性)二元式表示。

主程序流程


源程序存储在文件中,用一个字符串word存储识别的字符,通过read()函数读入文件中一个字符。
如果识别到空格,制表符等,直接通过read()读取下一个字符。
如果识别到字母,进入状态1的判断分支,然后读取下一个字符进行判断,如果为数字和字母则连接到word后,再读取下一个。直到结束后判断其是否为关键字或标识符。
如果识别到运算符或分割符,通过switch语句进行相应的判断,其余基本操作与上图和描述相似。

代码

package lexical;

import java.awt.EventQueue;

import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.awt.event.ActionEvent;
import java.awt.TextField;
import java.awt.TextArea;
import java.awt.Button;
import java.awt.Font;

public class Lexical_gui {

	private JFrame frame;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Lexical_gui window = new Lexical_gui();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Lexical_gui() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setTitle("\u8BCD\u6CD5\u5206\u6790\u5668");
		frame.setFont(new Font("Dialog", Font.PLAIN, 20));
		frame.setResizable(false);
		frame.setBounds(100, 100, 769, 454);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);

		TextArea textArea = new TextArea();
		textArea.setFont(new Font("Dialog", Font.PLAIN, 20));
		textArea.setBounds(38, 87, 696, 307);
		frame.getContentPane().add(textArea);

		TextField textField = new TextField();
		textField.setFont(new Font("Dialog", Font.PLAIN, 20));
		textField.setBounds(38, 28, 579, 38);
		frame.getContentPane().add(textField);

		Button button_1 = new Button("选择");
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int[] row_line = { 1, 0 };
				String word = "";
				int c;
				try {
					String filename = textField.getText();
					Reader r = new FileReader(filename);
					c = r.read();
					while (c != -1) {
						word = "";
						while (c == 32 || c == 9 || c == 10 || c == 13) {
							if (c == 10) {
								row_line[0] = row_line[0] + 1;
								row_line[1] = 0;
							}
							c = r.read();
						}
						if (isLetter(c)) {
							word = word + (char) c;
							row_line[1] = row_line[1] + 1;
							c = r.read();

							while (isLetter(c) || isNumber(c)) {
								word = word + (char) c;
								row_line[1] = row_line[1] + 1;
								c = r.read();

							}
							if (find_key(word)) {
								textArea.append(
										word + "\t1\t" + word + "\t关键字\t\t" + row_line[0] + "," + row_line[1] + '\n');
							} else {

								textArea.append(
										word + "\t6\t" + word + "\t标识符\t\t" + row_line[0] + "," + row_line[1] + '\n');
							}
						} else if (isNumber(c)) {
							word = word + (char) c;
							row_line[1] = row_line[1] + 1;
							c = r.read();

							while (isNumber(c)) {
								word = word + (char) c;
								row_line[1] = row_line[1] + 1;
								c = r.read();

							}
							textArea.append(
									word + "\t5\t" + word + "\t无符号数\t\t" + row_line[0] + "," + row_line[1] + '\n');
						} else if (c == 60 || c == 62) {
							word = word + (char) c;
							row_line[1] = row_line[1] + 1;
							c = r.read();

							if (c == 60 || c == 61 || c == 62) {
								word = word + (char) c;
								row_line[1] = row_line[1] + 1;
								c = r.read();

							}
							textArea.append(
									word + "\t4\t" + word + "\t关系运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
						} else {
							word = word + (char) c;
							row_line[1] = row_line[1] + 1;
							switch (word) {
							case "=":
								textArea.append(
										word + "\t3\t" + word + "\t算术运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "+":
								textArea.append(
										word + "\t3\t" + word + "\t算术运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "-":
								textArea.append(
										word + "\t3\t" + word + "\t算术运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "*":
								textArea.append(
										word + "\t3\t" + word + "\t算术运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "/":
								textArea.append(
										word + "\t3\t" + word + "\t算术运算符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "(":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case ")":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "[":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "]":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "{":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case "}":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case ",":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							case ";":
								textArea.append(
										word + "\t2\t" + word + "\t分界符\t\t" + row_line[0] + "," + row_line[1] + '\n');
								break;
							default:
								textArea.append(word + "\terror\t" + "-" + "\terror\t\t\t" + row_line[0] + ","
										+ row_line[1] + '\n');
							}
							c = r.read();

						}

					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});

		button_1.setBounds(627, 28, 107, 38);
		frame.getContentPane().add(button_1);

	}

	static boolean find_key(String x) {
		String[] k_table = { "int", "void", "main", "if", "else", "count" };
		boolean flag = false;
		for (int i = 0; i < k_table.length; i++) {
			if (k_table[i].equals(x))
				flag = true;
		}
		return flag;
	}

	static boolean isLetter(int x) {
		if ((x >= 97 && x <= 122) || (x >= 81 && x <= 106))
			return true;
		else
			return false;

	}

	static boolean isNumber(int x) {
		if (x >= 48 && x <= 57)
			return true;
		else
			return false;
	}
}

在文本框中选择源程序文件的绝对路径,点击选择按钮后运行结果。如果程序中有错误,进行报错。

测试源程序文件中的程序段如下:

int main(void)
{int a(=1;
	if(a>=1){
		count<<a+2;%%}
	else{
		count<<a+3;}}
posted @ 2020-01-21 13:58  启林O_o  阅读(243)  评论(0编辑  收藏  举报