采用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; 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); } }