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语言,提高了我的编程思维能力,增大了我的兴趣爱好,巩固了我的知识.还有好......

  

posted @   钟汉文  阅读(7906)  评论(1编辑  收藏  举报
编辑推荐:
· 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,谁才是开发者新宠?
点击右上角即可分享
微信分享提示