zoukankan      html  css  js  c++  java
  • 简单实现词法分析器

    说明

    • 开发语言: 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("u8BCDu6CD5u5206u6790u5668");
    		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 + "	1	" + word + "	关键字		" + row_line[0] + "," + row_line[1] + '
    ');
    							} else {
    
    								textArea.append(
    										word + "	6	" + word + "	标识符		" + row_line[0] + "," + row_line[1] + '
    ');
    							}
    						} 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 + "	5	" + word + "	无符号数		" + row_line[0] + "," + row_line[1] + '
    ');
    						} 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 + "	4	" + word + "	关系运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    						} else {
    							word = word + (char) c;
    							row_line[1] = row_line[1] + 1;
    							switch (word) {
    							case "=":
    								textArea.append(
    										word + "	3	" + word + "	算术运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "+":
    								textArea.append(
    										word + "	3	" + word + "	算术运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "-":
    								textArea.append(
    										word + "	3	" + word + "	算术运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "*":
    								textArea.append(
    										word + "	3	" + word + "	算术运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "/":
    								textArea.append(
    										word + "	3	" + word + "	算术运算符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "(":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case ")":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "[":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "]":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "{":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case "}":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case ",":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							case ";":
    								textArea.append(
    										word + "	2	" + word + "	分界符		" + row_line[0] + "," + row_line[1] + '
    ');
    								break;
    							default:
    								textArea.append(word + "	error	" + "-" + "	error			" + row_line[0] + ","
    										+ row_line[1] + '
    ');
    							}
    							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;}}
    
  • 相关阅读:
    安卓日志输出-logger
    RecyclerView的使用(3)之加入Header和Footer
    这些年我踩过的坑——Android
    精简点名IAP错误
    Android中BitmapFactory.Options详解
    在Android下通过ExifInterface类操作图片的Exif信息
    android 生成随机数
    JSON入门之二:org.json的基本使用方法
    Android中的各种访问权限Permission含义
    jar命令的用法详解
  • 原文地址:https://www.cnblogs.com/Qi-Lin/p/12221352.html
Copyright © 2011-2022 走看看