编译原理——词法分析器

采用java图形化界面编写了java语言的词法分析器,该分析器可识别所有java关键字。软件工程课程中编译原理实验。

Keyword.jvav

package org.kyc.test1;

public class Keyword {
	private String keyword; //存储关键字字符
	private int keywordindex;//存储关键字的下标
	Keyword[] keyW;//存储关键字对象的数组
	
	public Keyword(){
		//构造数组
		keyW=setKeywordList();
	}
	public Keyword(String str,int t){
		setKeyword(str);
		setKeywordindex(t);
		}
	public String getKeyword() {
		return keyword;
	}
	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}
	public int getKeywordindex() {
		return keywordindex;
	}
	public void setKeywordindex(int keywordindex) {
		this.keywordindex = keywordindex;
	}
	/**
	 * 创建关键字列表
	 * @return
	 */
	public  Keyword[] setKeywordList(){
		final int	PRIVATE=30;// private私有的
		final int	PROTECTED=31;// protected受保护的
		final int	PUBLIC=32 ;//public 公共的
			//类、方法和变量修饰符
		final int	ABSTRACT=33;//abstract 声明抽象
		final int	ClASS=34;// class类
		final int	EXTEND=35;//extends 扩允,继承
		final int   FINAL=36;//final 终极,不可改变的
		final int	IMPLEMENTS=37;//implements实现
		final int	INTERFACE=38;//interface 接口
		final int	NATIVE=39;//native 本地
		final int	NEW=40;//new 新,创建
		final int	STATIC=41;//static 静态 
		final int	STRICTFP=42;//strictfp 严格,精准
		final int	SYNCHRONIZED=43;//synchronized 线程,同步
		final int	TRANSIENT=44;//transient 短暂
		final int	VOLATILE=45;//volatile 易失

			//程序控制语句
		final int	BREAK=46;//break 跳出循环
		final int	CONTINUE=47;//continue 继续
		final int	RETURN=48;//return 返回
		final int	DO=49;//do 运行
		final int	WHILE=50;//while 循环
		final int	IF=51;//if 如果
		final int	ELSE=52;//	else 反之
		final int	FOR=53;//for 循环
		final int	INSTANCEOF=54;//instanceof 实例
		final int	SWITCH=55;//switch 开关
		final int	CASE=56;//case 返回开关里的结果
		final int	DEFAULT=57;//default 默认

			//错误处理
		final int	CATCH=58;//catch 处理异常
		final int	FINALLY=59;//finally 有没有异常都执行
		final int   THROW=60;//throw 抛出一个异常对象
		final int	THROWS=61;//throws 声明一个异常可能被抛出
		final int	TRY=62;//try 捕获异常

			//包相关
		final int	IMPORT=63;//import 引入
		final int   PACKAGE=64;//package 包

			//基本类型
		final int	BOOLEAN=65;//boolean 布尔型
		final int   BYTE=66;//byte 字节型
		final int   CHAR=67;//char 字符型
		final int	DOUBLE=68;//double 双精度,
		final int	FLOATE=69;//float 浮点
		final int	INT=70;//int 整型
		final int	LONG=71;//long 长整型
		final int	SHORT=72;//short 短整型
		final int	NULL=73;//null 空
		final int	TRUE=74;//true 真
		final int	FALSE=75;//false 假

			//变量引用
		final int	SUPER=76;//;super 父类,超类
		final int	THIS=77;//this 本类
		final int	VOID=78;//void 无返回值
		final int   CONST=80;//const
		final int   GOTO=81;//goto
		
		Keyword kwTable[] = { 
				new Keyword("private", PRIVATE),
				new Keyword("protected", PROTECTED),
				new Keyword("public",	PUBLIC),
				//类、方法和变量修饰符
				new Keyword("abstract"	,ABSTRACT), // 声明抽象
				new Keyword("class",	ClASS), // 类
				new Keyword("extends"	,EXTEND), // 扩允,继承
				new Keyword("final"   ,FINAL), // 终极,不可改变的
				new Keyword("implements"	,IMPLEMENTS), //实现
				new Keyword("interface",	INTERFACE), // 接口
				new Keyword("native",	NATIVE), // 本地
				new Keyword("new"	,NEW),// 新,创建
				new Keyword("static"	,STATIC), // 静态 
				new Keyword("strictfp" ,	STRICTFP), //严格,精准
				new Keyword("synchronized",SYNCHRONIZED), // 线程,同步
				new Keyword("transient"	,TRANSIENT), // 短暂
				new Keyword("volatile"	,VOLATILE), // 易失

					//程序控制语句
				new Keyword("break"	,BREAK), // 跳出循环
				new Keyword("continue"	,CONTINUE), // 继续
				new Keyword("return" ,	RETURN), //返回
				new Keyword("do"	,DO), // 运行"
				new Keyword("while"	,WHILE), //循环
				new Keyword("if",IF), // 如果
				new Keyword("else"	,ELSE), //	 反之
				new Keyword("for"	,FOR), // 循环
				new Keyword("instanceof	",INSTANCEOF), // 实例
				new Keyword("switch ",	SWITCH), //开关
				new Keyword("case",	CASE), // 返回开关里的结果
				new Keyword("default",	DEFAULT), // 默认

					//错误处理
				new Keyword("catch", 	CATCH), //处理异常
				new Keyword("finally",	FINALLY), // 有没有异常都执行
				new Keyword("throw",  THROW), //抛出一个异常对象
				new Keyword("throws",	THROWS), // 声明一个异常可能被抛出
				new Keyword("try",	TRY), // 捕获异常

					//包相关
				new Keyword("import",	IMPORT), // 引入
				new Keyword("package",   PACKAGE), // 包

					//基本类型
				new Keyword("boolean",	BOOLEAN), // 布尔型
				new Keyword("byte",   BYTE), // 字节型
				new Keyword("char",   CHAR), // 字符型
				new Keyword("double",	DOUBLE), // 双精度,
				new Keyword("float",	FLOATE), // 浮点
				new Keyword("int",	INT),// 整型
				new Keyword("long",	LONG), // 长整型
				new Keyword("short",	SHORT), // 短整型
				new Keyword("null",	NULL), // 空
				new Keyword("true",	TRUE), // 真
				new Keyword("false",	FALSE), // 假

					//变量引用
				new Keyword("super",	SUPER), //, 父类,超类
				new Keyword("this",	THIS), // 本类
				new Keyword("void",	VOID), // 无返回值
				new Keyword("const" ,  CONST),
				new Keyword("goto",   GOTO), 
				};
		return kwTable;
	}
	/*
	 * 判断字符串是否为关键字
	 */
	public boolean isKeyWord(String str){
		
		boolean b=false;
		for(int i=0;i<keyW.length;i++){
			if(keyW[i].getKeyword().equals(str)||keyW[i].getKeyword()==str){
				b=true;
				break;	
			}
		}
		return b;
		}
	}
package org.kyc.test1;

public class Operators {
	private String strOperators;
	private int flagOperators;
	private Operators[] oper;
	public Operators(){
		oper=setOperators();
		
	}
	public Operators(String str,int t){
		strOperators=str;
		flagOperators=t;
	}
	public String getStrOperators() {
		return strOperators;
	}
	public void setStrOperators(String strOperators) {
		this.strOperators = strOperators;
	}
	public int getFlagOperators() {
		return flagOperators;
	}
	public void setFlagOperators(int flagOperators) {
		this.flagOperators = flagOperators;
	}
	/**
	 * 创建操作符列表
	 * @return Operators[]
	 */
	public Operators[] setOperators(){

		Operators operators[]={
				new Operators(".",101),
				new Operators("(",102),
				new Operators(")",103),
				new Operators("[",104),
				new Operators("]",105),
				new Operators("+",106),
				new Operators("-",107),
				new Operators("++",108),
				new Operators("--",109),
				new Operators("~",110),
				new Operators("!",111),
				new Operators("*",112),
				new Operators("/",113),
				new Operators("//",114),
				new Operators("<<",115),
				new Operators(">>",116),
				new Operators(">>>",117),
				new Operators(">",118),
				new Operators(">=",119),
				new Operators("<=",120),
				new Operators("==",121),
				new Operators("!=",122),
				new Operators("&",123),
				new Operators("|",124),
				new Operators("?",125),
				new Operators(":",126),
				new Operators("=",127),
				new Operators("+=",128),
				new Operators("-=",129),
				new Operators("/=",130),
				new Operators("%=",131),
				new Operators("&=",132),
				new Operators("|=",133),
				new Operators("^=",134),
				new Operators("<<=",135),
				new Operators(">>=",136),
				new Operators(">>>=",137),
				new Operators(";",140),
				new Operators("{",141),
				new Operators("}",142),
				new Operators("\"",143),
				new Operators("\'",144),
				new Operators("@",145),
				new Operators("$",146),
				new Operators("\\",147),
				new Operators(",",148)
		};
		return operators;
	}
	public boolean isOperator(String str){
		// 判断字符是否是操作符
		
		boolean b=false;
		for(int i=0;i<oper.length;i++){
			if(oper[i].getStrOperators().equals(str)||oper[i].getStrOperators()==str){
				b=true;
				break;
			}
		}
		return b;

	}
	public boolean isOperator(char c){
		// 判断字符是否是操作符
		
		boolean b=false;
		for(int i=0;i<oper.length;i++){
			if(oper[i].getStrOperators().equals(c)||oper[i].getStrOperators().charAt(0)==c){
				b=true;
				break;
			}
		}
		return b;
	}
	public int getNumber(String str){
		//返回与字符对应的数字
		int f=0;
		for(int i=0;i<oper.length;i++){
			if(oper[i].getStrOperators().equals(str)||oper[i].getStrOperators()==str){
				f=oper[i].getFlagOperators();
				break;
			}
		}
		return f;
	}
	public int getNumber(char c){
		int f=0;
		for(int i=0;i<oper.length;i++){
			if(oper[i].getStrOperators().equals(c)||oper[i].getStrOperators().charAt(0)==c){
				f=oper[i].getFlagOperators();
				break;
			}
		}
		return f;
	}
}

package org.kyc.test1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class CharacterAnalysis {
	final int ERROR=0;//错误
	final int LETTER=1;//字母
	final int NUM=2;//数字
	final int NOTE=3;//注释的

	
	private char[] prog;//存储所扫描的程序
	

	private int progIndex;//扫描的下标

	private String token;//获取到的字符串
	final int PROG_SIZE = 1000000;

	// 将关键字的外部表示,和内部表示保存在一个名为KeyWordTable的表中
	Keyword keyword=new Keyword();
	Keyword keywordTable[] =keyword.setKeywordList();
	
	Operators operator=new Operators();
	Operators operatorsTable[]=operator.setOperators();

	Object [][] list=new Object[65635][2];
	int List_index=0;
	
	public CharacterAnalysis(File file_choosed) throws IOException {
		//实现将文件中的字符存到数组中
		char tempbuf[] = new char[PROG_SIZE];
		int size=0;
		try {
			FileReader fr = new FileReader(file_choosed);
			BufferedReader br = new BufferedReader(fr);
			size = br.read(tempbuf, 0, PROG_SIZE);
			fr.close();
		} catch (FileNotFoundException exc) {
			System.out.print("没有找到该文件!");
		}
		if (size != -1) {
			prog = new char[size];
			System.arraycopy(tempbuf, 0, prog, 0, size);	
		}
	}

	public void Analyse(String str){
		this.prog=str.toCharArray();
		try {
			Analyse();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void Analyse() throws IOException {
		// 对代码扫描
		do {
			token = "";
			// 跳过空格符
			while(isSpaceOrTab(prog[progIndex])||isnextline(prog[progIndex])){
				
			while (isSpaceOrTab(prog[progIndex])){
				progIndex++;
				if(progIndex>=prog.length)break;
			}
			
			// 处理换行
			while (isnextline(prog[progIndex])) {
				progIndex ++;
				if(progIndex>=prog.length)break;
			}
			if(progIndex>=prog.length)break;
			}
			if(progIndex>=prog.length){
				break;
			}
			/*
			 * 判断是否为注释,并作处理
			 */
			else if(isMark()){
				System.out.println("注释:"+token+"  "+NOTE);
		
				AddTolist("注释:"+token,NOTE);
				continue;
			}
			/*
			 *    是一个操作符,或者是运算符
			 */
			else if (operator.isOperator(prog[progIndex])) {
				//System.out.println("是个操作符");
				token += prog[progIndex];
				progIndex++;
				//继续判断是否为两个符号组成在一起的操作符
				if (operator.isOperator(prog[progIndex])){
					//判端接下来的操作符是否和前面的操作符能够组成在一起
					token += prog[progIndex];
					progIndex++;
					if (operator.isOperator(token)){
						//说明组成在一起了
						System.out.println(token+"  "+operator.getNumber(token));
						AddTolist(token,operator.getNumber(token));
						continue;
					}
					else{
						//说明组不到一起
						System.out.println(token.charAt(0)+" "+operator.getNumber(token.charAt(0)));
						System.out.println(token.charAt(1)+" "+operator.getNumber(token.charAt(1)));
						AddTolist(token.charAt(0),operator.getNumber(token.charAt(0)));
						AddTolist(token.charAt(1),operator.getNumber(token.charAt(1)));
						continue;
					}
				}
				else{
					System.out.println(token+"  "+operator.getNumber(token));
					AddTolist(token,operator.getNumber(token));
					continue;
				}
				
			} 
			/*
			 * 是一个字符变量
			 */
			else if (Character.isLetter(prog[progIndex])) {
				
				while (Character.isLetterOrDigit(prog[progIndex])||prog[progIndex]=='_') {
					//System.out.println("是个字符变量");
					token += prog[progIndex];
					progIndex++;
					if (progIndex >= prog.length)
						break;
				}

				if (keyword.isKeyWord(token)){
					//说明是关键字
					for(int i=0;i<keywordTable.length;i++){
						if(token.equals(keywordTable[i].getKeyword())||token==keywordTable[i].getKeyword()){
							System.out.println(token+"   "+keywordTable[i].getKeywordindex());
							AddTolist(token,keywordTable[i].getKeywordindex());
							break;
						}
					}
				}
				
				else{
					System.out.println(token + "   " + LETTER);
					AddTolist(token, LETTER);
				}
					
			} 
			/*
			 *  是一个数字字符
			 */
			else if (Character.isDigit(prog[progIndex])) {
				
				while (Character.isDigit(prog[progIndex])) {
					token += prog[progIndex];
					progIndex++;
					if (progIndex >= prog.length)
						break;
				}
				System.out.println(token + "   " +NUM );
				AddTolist(token, NUM);
			}

			else  {
				System.out.println(token+"  "+ERROR);
				AddTolist(token, ERROR);
				progIndex++;
				continue;
				
			}
		} while (progIndex != prog.length);
	
		System.out.println("程序分析完毕");

	}


	


	private boolean isMark() {
		// TODO Auto-generated method stub
		//判断是否为注释部分
		if(prog[progIndex]=='/'&&prog[progIndex+1]=='/'){
			
			while(!isnextline(prog[progIndex])){
				token += prog[progIndex];
				progIndex++;
			}
		
			return true;
		}
		return false;
	}

	//判断是否为空格
	private boolean isSpaceOrTab(char c) {
		if (c == ' ' || c == '\t')
			return true;
		return false;
	}

	//判断是否为换行
	private boolean isnextline(char c){
		if(c== '\r'||c == '\n'){
			return true;
		}
		else{
			return false;
		}
		
	}

	public char[] getProg() {
		return prog;
	}
	public void AddTolist(String str,int num){
		list[List_index][0]=str;
		list[List_index][1]=num;
		List_index++;
	}
	private void AddTolist(char charAt, int num) {
		// TODO Auto-generated method stub
		list[List_index][0]=charAt;
		list[List_index][1]=num;
		List_index++;
	}
}

package org.kyc.test1;


package org.kyc.test1;


import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import java.awt.Font;

/**
 * 编译原理实验一——词法分析器
 * @author 康雨城
 * 2015/6/4
 */
public class View extends JFrame {

	private JPanel contentPane;
	private JFileChooser fc;
	private JTextArea textArea;
	private CharacterAnalysis ob;
	private JTable table;
	private File file_choosed;

	String [] cloumnNames= {"词语","分析结果"};
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					View frame = new View();
					frame.setVisible(true);
					frame.setTitle("词法分析器");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public View() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 750, 400);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new GridLayout(1, 2, 0, 0));
		
		fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		
		
		JPanel panel = new JPanel();
		contentPane.add(panel);
		panel.setLayout(null);
		
		JPanel panel_Left = new JPanel();
		panel_Left.setBounds(0, 297, 362, 54);
		panel.add(panel_Left);
		panel_Left.setLayout(new GridLayout(1, 2, 0, 0));
		
	
		JScrollPane Left_ScrollPane = new JScrollPane();
		Left_ScrollPane.setBounds(0, 0, 362, 297);
		panel.add(Left_ScrollPane);
		
		textArea = new JTextArea();
		Left_ScrollPane.setViewportView(textArea);
		
		JScrollPane RightScrollPane = new JScrollPane();
		contentPane.add(RightScrollPane);
		
		
		JButton btnSelectFile = new JButton("选取文件");
		btnSelectFile.setFont(new Font("宋体", Font.BOLD, 18));
		btnSelectFile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int i=fc.showOpenDialog(null);
				if(i==fc.APPROVE_OPTION){
					
				file_choosed = fc.getSelectedFile();
				
				try {
					ob = new CharacterAnalysis(file_choosed);
				
					textArea.setText(String.valueOf(ob.getProg()));
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					}	
				}
				else {
					System.out.println("没有选择文件");
				}
			}
		});
		panel_Left.add(btnSelectFile);
		

		JButton btnAnalysis = new JButton("分析");
		btnAnalysis.setFont(new Font("宋体", Font.BOLD, 18));
		btnAnalysis.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					if(file_choosed==null){
						System.out.println("请选择文件!");
					}
					else{
						ob.Analyse();	
						table=new JTable(ob.list,cloumnNames);
						RightScrollPane.setViewportView(table);
						table.invalidate();
					}
					
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		panel_Left.add(btnAnalysis);
	}
}


猜你喜欢

转载自blog.csdn.net/kangyucheng/article/details/47453391