Java语言词法分析器
一、实验目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示).
二、实验准备工作
1、词法分析器的功能和输出格式
词法分析器的功能是输入源程序,输出单词符号。词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。本实验中,采用的是一类符号一种别码的方式。
2、Java程序语言的单词符号的种别.
识别java的关键字:
boolean,byte,char,double,false,float,int,long,new,null,short,true,void,instanceof,break,case,catch,continue,default,do,else,for,if,return,switch,try,while,finally,throw,this,super,abstract,final,namtive,private,protected,public ,static,synchronized,transient,volatile,class,extends,implements,interface,package,import,throws;单词识别码为1;
标识符:标识符必须是以字母,下划线,美元符号开始,单词识别码为2;
常量:常数为无符号整形数;单词种别码为3;
运算符:+、-、*、/、=、>、<、>=、<=、==、!= 、++、--、%、&&、||、!单词识别码为4;
分隔符:,、;、{、}、(、); 单词种别码为5
4.单元模块
//业务代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.Vector; public class JavaAnaylsis { private static String[] keyword = { "boolean" , "byte" , "char" , "double" , "false" , "float" , "int" , "long" , "new" , "null" , "short" , "true" , "void" , "instanceof" , "break" , "case" , "catch" , "continue" , "default" , "do" , "else" , "for" , "if" , "return" , "switch" , "try" , "while" , "finally" , "throw" , "this" , "super" , "abstract" , "final" , "namtive" , "private" , "protected" , "public" , "static" , "synchronized" , "transient" , "volatile" , "class" , "extends" , "implements" , "interface" , "package" , "import" , "throws" }; static String string; static String wordString; static Vector vc; public JavaAnaylsis(String str) throws Exception { File inFile = new File(str); if (inFile.exists()) { System.out.println( "文件打开成功!!!" ); try { FileReader reader = new FileReader(inFile); BufferedReader br = new BufferedReader(reader); vc = new Vector(); while ((string = br.readLine()) != null ) { // 预处理 将一行的字符串连续的空格换成一个空格或将连续的制表符换成一个空格 string = string.trim().replace( " +" , " " ) .replaceAll( "\\t+" , " " ); // System.out.println(string); judgement(); } br.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { System.out.println( "文件打开失败" ); } } /* * 判断读入的字符是否为字母 */ public static boolean isLetter( char c) { if ((c >= 'a' && c <= 'z' ) || (c > + 'A' && c <= 'Z' )) { return true ; } else return false ; } /* * 判断读入的字符是否为数字 */ public static boolean isDigit( char c) { if (c >= '0' && c <= '9' ) { return true ; } else return false ; } /* * 判断是否为关键字 */ public static boolean isKey(String ss) { int flag = 0 ; for ( int i = 0 ; i < keyword.length; i++) { if (ss.equals(keyword[i])) { flag = 1 ; break ; } } if (flag == 1 ) { return true ; } return false ; } /* * 判断是否为运算符 */ public static boolean isSpilt( char ch) { if (ch == '+' || ch == '-' || ch == '|' || ch == '=' || ch == '&' ) { return true ; } else return false ; } /* * 判断输入的字符并输出单词符号 */ public static void judgement() throws Exception { char ch = 0 ; int m = 0 ; String str = null ; for ( int i = 0 ; i < string.length(); i++) { switch (m) { case 0 : ch = string.charAt(i); // 判断是否为运算符使用超前搜索 if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=' || ch == '>' || ch == '<' || ch == '!' || ch == '%' || ch == '|' ) { str = "" ; str += ch; if (ch == '+' || ch == '-' || ch == '>' || ch == '<' || ch == '!' || ch == '|' || ch == '&' ) { ch = string.charAt(i + 1 ); // 对下一个字符进行判断是否为运算符 if (isSpilt(ch)) { str += ch; m = 4 ; } else { ch = string.charAt(i - 1 ); // 不是运算符则进行回退操作 m = 4 ; } } } // 判断是否为界符 else if (ch == ',' || ch == ';' || ch == '{' || ch == '}' || ch == '(' || ch == ')' ) { m = 5 ; } // 判断是否数字 else if (isDigit((ch = string.charAt(i)))) { str = "" ; str += ch; m = 3 ; } // 判断是否字母 else if (isLetter(ch = string.charAt(i))) { str = "" ; str += ch; m = 2 ; } // 判断是否下划线或美元符号 else if (ch == '_' || ch == '$' ) { str = "" ; str += ch; m = 2 ; } else { } break ; case 4 : i--; System.out.println(( "( 4 " + "“ " + str + " ” )" )); wordString = ( "( 4 " + "“ " + str + " ” )" ); vc.add(wordString); m = 0 ; break ; case 5 : i--; System.out.println(( "( 5 " + "“ " + ch + " ” )" )); wordString = ( "( 5 " + "“ " + ch + " ” )" ); vc.add(wordString); m = 0 ; break ; case 2 : if (isLetter(ch = string.charAt(i))) { str += ch; } else { if (isKey(str)) { System.out.println( "( 1 " + "“ " + str + " ” )" ); wordString = ( "( 1 " + "“ " + str + " ” )" ); vc.add(wordString); } else { System.out.println(( "( 2 " + "“ " + str + " ” )" )); wordString = ( "( 2 " + "“ " + str + " ” )" ); vc.add(wordString); } i--; m = 0 ; } break ; case 3 : if (isDigit((ch = string.charAt(i)))) { str += ch; } else { System.out.println( "( 3 " + "“ " + str + " ” )" ); wordString = "( 3 " + "“ " + str + " ” )" ; vc.add(wordString); i--; m = 0 ; } break ; } } } public static Vector getVector() { return vc; } } |
//界面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; import java.util.Vector; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.WindowConstants; public class JavaFrame extends JFrame { private JTextArea textArea, textArea2; private JButton anaylisbButton; static String filename; static Vector vcVector; public JavaFrame() { super (); setTitle( "Java词法分析器" ); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 设置"关闭"按钮处理事件 Toolkit tool = Toolkit.getDefaultToolkit(); // 创建工具栏 Dimension screenSize = tool.getScreenSize(); // 获得屏幕大小 setSize( 800 , 500 ); // 设置窗体大小 setLocation((screenSize.width - getWidth()) / 2 , (screenSize.height - getHeight()) / 2 ); JPanel scollJPanel = (JPanel) getContentPane(); // 获得内容面板 setResizable( false ); // 设置最大化按钮不能用 JMenuBar menuBar = createMenu(); // 设置菜单项 this .setJMenuBar(menuBar); // textArea=new TextArea(); JScrollPane jScrollPane = new JScrollPane(textArea = new JTextArea( "源代码:" + "\n" , 1000 , 35 )); JScrollPane jScrollPane2 = new JScrollPane(textArea2 = new JTextArea( "词法分析后:" + "\n" , 1000 , 35 )); scollJPanel.add(jScrollPane2, BorderLayout.EAST); scollJPanel.add(jScrollPane, BorderLayout.WEST); JPanel buttonJPanel = new JPanel(); anaylisbButton = new JButton( "开始词法分析" ); anaylisbButton.addActionListener( new start()); buttonJPanel.add(anaylisbButton); scollJPanel.add(buttonJPanel, "South" ); setVisible( true ); } private JMenuBar createMenu() { // TODO Auto-generated method stub JMenuBar menuBar = new JMenuBar(); // 初始化菜单栏 JMenu menu = new JMenu( " 文件 " ); JMenu menu2 = new JMenu( " 窗口 " ); menu2.setEnabled( false ); JMenu menu3 = new JMenu( " 帮助 " ); menu3.setEnabled( false ); JMenu menu4 = new JMenu( " 格式 " ); menu4.setEnabled( false ); JMenuItem meun1 = new JMenuItem( " 打开 " ); JMenuItem meun2 = new JMenuItem( " 保存 " ); JMenuItem meun3 = new JMenuItem( " 另存为 " ); JMenuItem meun4 = new JMenuItem( " 退出 " ); meun4.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub JavaFrame. this .dispose(); } }); meun1.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub // 初始化文件选择框 textArea.setText( "源代码:" + "\n" ); JFileChooser fDialog = new JFileChooser( "d:/" ); // 设置文件选择框的标题 fDialog.setDialogTitle( "请选择文件" ); // 弹出选择框 int returnVal = fDialog.showOpenDialog( null ); // 如果是选择了文件 if (JFileChooser.APPROVE_OPTION == returnVal) { // 打印出文件的路径,你可以修改位 把路径值 写到 textField 中 System.out.println(fDialog.getSelectedFile()); filename = fDialog.getSelectedFile().toString(); File inFile = new File(filename); try { FileReader reader = new FileReader(inFile); BufferedReader br = new BufferedReader(reader); String strings; while ((strings = br.readLine()) != null ) { textArea.append(strings + "\n" ); } br.close(); } catch (Exception e) { // TODO: handle exception } } } }); meun2.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub JFileChooser jf = new JFileChooser( "d:/" ); int value = jf.showSaveDialog( null ); if (value == JFileChooser.APPROVE_OPTION) { // 判断窗口是否点的是打开或保存 File getPath = jf.getSelectedFile(); // 取得路径 System.out.println(getPath); try { FileWriter fWriter = new FileWriter(getPath); BufferedWriter out = new BufferedWriter(fWriter); Iterator iterator = vcVector.iterator(); while (iterator.hasNext()) { // textArea2.append(iterator.next().toString()+"\n"); out.write(iterator.next().toString()); out.newLine(); } out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { // 没有选择,即点了窗口的取消 } } }); menu.add(meun1); menu.add(meun2); menu.add(meun3); menu.addSeparator(); menu.add(meun4); menuBar.add(menu); menuBar.add(menu2); menuBar.add(menu4); menuBar.add(menu3); return menuBar; } private class start implements ActionListener { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub textArea2.setText( "词法分析后:" + "\n" ); try { new JavaAnaylsis(filename); vcVector = new Vector(); vcVector = JavaAnaylsis.getVector(); Iterator iterator = vcVector.iterator(); while (iterator.hasNext()) { textArea2.append(iterator.next().toString() + "\n" ); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { new JavaFrame(); } }<br><br> |

实验总结:我在编程的过程中一共花了一天的时间,而在纸上设计就大概花了半个小时吧,花了半天的时间去上机输入和调试,在这次的实验过程中花了近半天的时间去思考问题,也遇到了编程的过程的问题,主要在逻辑错误问题较多,开始时我以为我的逻辑无错误,还以为是其他的问题,最后静下来理清自己的逻辑,还是发现了出现了较严重的逻辑问题,通过在网上查阅相关的资料来解决问题.到最后还是基本完成了这个java词法分析器的实验.对于我自己的程序我认为还是可以应对基本的词法分析,能编出这个程序我感觉到有那么一点成就感,这次的实验让我进一步地熟悉了java语言,提高了我的编程思维能力,增大了我的兴趣爱好,巩固了我的知识.还有好......
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?