词法分析器设计

更新时间:2023-11-06 21:03:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

计算机专业软件类课程实验报告

课程名称: 实验题目: 实验小组成员:实验小组组长:任课教师: 专业名称: 班级名称: 实验起止时间:

编译原理

词法分析器设计

计算机科学与技术

计科1班

2014-5-8~2014-5-15

一、实验目的

1、要求设计交互界面,能输入能转换能输出,形式和风格自定。

2、设计一个词法分析程序,理解词法分析器实现的原理,掌握程序设计语言中的各类单词的词法分析方法,加深对词法分析原理的理解。

二、实验内容

1、对给定的程序通过词法分析器能够识别一个个单词符号,并以三元式(单词行号,单词符号的属性值,单词符号类别)显示。如果有错误,统计总共有多少个错误,并且将每个错误所在行号,以及属于哪种错误显示出来。

2.本程序自行规定: (1)关键字

\\\\\ \\\\\\ \ (2)运算符

\(3)界符

\(4)标识符

以字母或下划线开头的字符串表示 (5)常量

用数字表示

(6)空格、回车、换行符跳过

3、在屏幕上显示如下: (1)Token表中显示: 1 program 保留字 1 example 保留字 1 ; 界符 2 const 保留字 2 k 标识符 2 = 运算符 2 200 常量

(2)错误信息显示:

2errors

4 2a 格式不正确 4 034 不能以0开头

三、实验需求

1、界面部分:

需要对文件有打开、保存、另存为的功能;对文本有撤销、剪切、复制、粘贴、复制、删除、全选的功能

2、词法分析器:

对读入的程序一个字符一个字符的进行词法分析,识别出一个个单词符号,并以三元式(单词行号,单词符号的属性值,单词符号类别)显示。如果有错误,统计总共有多少个错误,并且将每个错误所在行号,以及属于哪种错误显示出来。

四、主要数据结构介绍

使用三个数组分别来存放关键字、运算符、界符,凡是不属于这三个数组的所有合法字符串当做标识符处理,凡是不属于这三个数组的所有合法数字当做常量处理,其余情况则进行出错处理

五、主要模块算法介绍

1、对输入的程序进行处理:空格、回车、换行符跳过,并按照\、\、\、\等符号将字符串切割开来,同时对字符串使用toCharArray()转换成单个字符,求出切割符号在字符串中的位置,并将它们与切割好的字符串重新组合,使它们与输入程序相同

2、对第一步得到的字符串数组进行一个一个的检查,如果字符串在table1中,则表明是运算符,将状态标记为1;如果字符串在table2中,则表明是保留字,将状态标记为2;如果字符串在table3中,则表明是界符,将状态标记为3

3、如果对当前的字符串不在这三个数组中,且数字序列又是合法的,则表明是常量,将状态标记为4;如果对当前的字符串不在这三个数组中,且字符序列又是合法的,则表明是标识符,将状态标记为5

4、如果对当前的输入不满足前5个状态,且字符序列不是以下划线、字母开头,则表明输入的格式不正确,将状态标记为6;如果对当前的输入不满足前5个状态,且字符序列是以0开头的数字序列,则表明输入的常量是以0开头的,这是非法格式,将状态标记为7

5、将最终的结果打印输出到文本框中

六、程序实现环境及使用说明

本次实验采用Eclipse进行代码的编写、编译及运行;

编写语言为java语言; 程序的运行环境为jdk1.8; 系统为windows 8.1

七、实验测试用例设计说明

1、正常的测试,这种情况下不会报错 program example; const k=2; var

a:interger; begin end

2、错误的测试,这个例子中含有非法标识符和非法常量的错误 program example;

const k=2a,c=300,d=034; var

a:interger; begin end

八、实验结果测试情况

九、小组对实验结果的自我评价

通过这次实验,我对词法分析器有了一定的了解,进一步的巩固了这部分的知识。懂得了词法分析器的工作原理。在编程过程中,遇到了不少的问题,在同学的帮助下,问题一步一步的得到了解决。先从实现最简单的扫描和输出,再实现扫描的范围扩大和输出的结果更加具体,虽然词法分析器的功能实现了,但是对于小数不能进行较好的分析。在算法上虽然是弄懂了词法分析器,但具体实现起来还有一些不足。由于编程能力和时间的不足,这个分析器还有待完善,没有把双目运算符考虑进来。对于出错处理也考虑得不够周到。望老师多多指教。

十、任课教师对实验结果的评分

源码

FrameView.java

package view;

import java.awt.BorderLayout; import java.awt.Event; import java.awt.FileDialog; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridLayout; import java.awt.ScrollPane;

import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; 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 javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTextArea; import javax.swing.KeyStroke;

import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.UndoableEditEvent;

import javax.swing.event.UndoableEditListener; import javax.swing.undo.UndoManager;

import operation.Analysis;

public class FrameView extends JFrame implements ActionListener,

JMenuBar bar = new JMenuBar(); JMenu file = new JMenu(\文件\); JMenu edit = new JMenu(\编辑\);

JMenu analysis = new JMenu(\词法分析\); JMenu help = new JMenu(\帮助\);

JMenuItem open = new JMenuItem(\打开\); JMenuItem save = new JMenuItem(\保存\); JMenuItem saveNew = new JMenuItem(\另存为\); JMenuItem exit = new JMenuItem(\退出\); JMenuItem back = new JMenuItem(\撤销\); JMenuItem cut = new JMenuItem(\剪切\); JMenuItem copy = new JMenuItem(\复制\); JMenuItem paste = new JMenuItem(\粘贴\); JMenuItem del = new JMenuItem(\删除\); JMenuItem all = new JMenuItem(\全选\);

JMenuItem lexical = new JMenuItem(\词法分析器\); JMenuItem sHelp = new JMenuItem(\查看帮助\); JMenuItem about = new JMenuItem(\关于\); JFrame f = new JFrame(\词法分析器\); ScrollPane jspa = new ScrollPane(); ScrollPane jspb = new ScrollPane(); ScrollPane jspc = new ScrollPane(); JPopupMenu pop = new JPopupMenu(); JTextArea ta = new JTextArea(); JTextArea tb = new JTextArea(); JTextArea tc = new JTextArea(); JPanel pa = new JPanel(); JPanel pb = new JPanel();

JOptionPane jop = new JOptionPane(); UndoManager um = new UndoManager();

DocumentListener, UndoableEditListener {

public void setup() {

setLayout(new BorderLayout()); }

ta.setFont(new Font(\宋体\, 0, 20)); ta.setLineWrap(true); tb.setEditable(false); tc.setEditable(false); pack();

f.setBounds(300, 100, 750, 550); f.setVisible(true);

f.addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent we) { }

if ((isSave == false) && (change == true)) { Prompt dg = new Prompt(f, \词法分析器\, true); } else

System.exit(0);

setup();

public FrameView() {

isSave = false; change = false; isLine = true;

JMenuItem back1 = new JMenuItem(\撤销\); JMenuItem cut1 = new JMenuItem(\剪切\); JMenuItem copy1 = new JMenuItem(\复制\); JMenuItem paste1 = new JMenuItem(\粘贴\); JMenuItem del1 = new JMenuItem(\删除\); JMenuItem all1 = new JMenuItem(\全选\);

FileDialog openDia = new FileDialog(f, \打开\, FileDialog.LOAD); FileDialog saveDia = new FileDialog(f, \保存\, FileDialog.SAVE); AboutFile prompta; File fe;

Clipboard clipboard = null; boolean isSave, change, isLine; String select;

});

f.setJMenuBar(bar); jspa.add(ta); jspb.add(tb); jspc.add(tc);

pb.setLayout(new GridLayout(2, 1)); pb.add(jspb); pb.add(jspc);

pa.setLayout(new GridLayout(1, 2)); pa.add(jspa); pa.add(pb); f.add(pa); bar.add(file); bar.add(edit); bar.add(analysis); bar.add(help); file.add(open); file.add(save); file.add(saveNew); file.addSeparator(); file.add(exit); edit.add(back); edit.addSeparator(); edit.add(cut); edit.add(copy); edit.add(paste); edit.add(del); edit.addSeparator(); edit.addSeparator(); edit.add(all); edit.addSeparator(); analysis.add(lexical); help.add(sHelp); help.add(about); pop.add(back1); pop.addSeparator(); pop.add(cut1); pop.add(copy1); pop.add(paste1);

pop.add(del1); pop.addSeparator(); pop.add(all1);

open.setMnemonic('O');

open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,

Event.CTRL_MASK));

save.setMnemonic('S');

save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,

Event.CTRL_MASK));

saveNew.setMnemonic('A');

saveNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,

Event.SHIFT_MASK));

exit.setMnemonic('X');

exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,

Event.SHIFT_MASK));

back.setMnemonic('Z');

back.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,

Event.CTRL_MASK));

cut.setMnemonic('X');

cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,

Event.CTRL_MASK));

copy.setMnemonic('C');

copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,

Event.CTRL_MASK));

paste.setMnemonic('V');

paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,

Event.CTRL_MASK));

del.setMnemonic('L');

del.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, all.setMnemonic('A');

all.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,

Event.CTRL_MASK));

lexical.setMnemonic('L');

lexical.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,

Event.CTRL_MASK));

sHelp.setMnemonic('H');

sHelp.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H,

Event.SHIFT_MASK));

about.setMnemonic('B');

about.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B,

Event.SHIFT_MASK));

back1.setMnemonic('Z');

0));

back1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,

Event.CTRL_MASK));

cut1.setMnemonic('X');

cut1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,

Event.CTRL_MASK));

copy1.setMnemonic('C');

copy1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,

Event.CTRL_MASK));

paste1.setMnemonic('V');

paste1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,

Event.CTRL_MASK));

del1.setMnemonic('L');

del1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, all1.setMnemonic('A');

all1.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,

Event.CTRL_MASK));

0));

open.addActionListener(this); save.addActionListener(this); saveNew.addActionListener(this); exit.addActionListener(this); back.addActionListener(this); cut.addActionListener(this); copy.addActionListener(this); paste.addActionListener(this); del.addActionListener(this); all.addActionListener(this); lexical.addActionListener(this); about.addActionListener(this); sHelp.addActionListener(this); back1.addActionListener(this); cut1.addActionListener(this); copy1.addActionListener(this); paste1.addActionListener(this); del1.addActionListener(this); all1.addActionListener(this);

ta.getDocument().addDocumentListener(this); ta.getDocument().addUndoableEditListener(this);

'_')) {

if (temp[0] >= '1' && temp[0] <= '9') { for (int m = 1; m < temp.length; m++) { if (temp[m] < '0' || temp[m] > '9') { judge = 1;

// System.out.println(\格式不正确\ statue = 6; print(i); break;

}

}

if (judge == 0) { // System.out.println(\常量\ statue = 4; print(i);

}

} else if (temp[0] == '0') {

if (temp.length > 1) { // System.out.println(\不能以0开头\ statue = 7; print(i); } else {

statue = 4; print(i);

} } else if ((temp[0] >= 'a' && temp[0] <= 'z')

|| (temp[0] >= 'A' && temp[0] <= 'Z') || (temp[0] == for (int m = 1; m < temp.length; m++) { if ((temp[m] >= '0' && temp[m] <= '9') || (temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z')

|| (temp[0] == '_')) {

judge = 0; } else {

judge = 1; break;

}

}

if (judge == 0) { // System.out.println(\标识符\ statue = 5; print(i);

} else {

// System.out.println(\格式不正确\

}

}

}

}

statue = 6; print(i);

} else {

// System.out.println(\格式不正确\ statue = 6; print(i);

public void print(int i) {

switch (statue) { case 1:

// System.out.println(\运算符\

list += row + \ + cache[i] + \ + \运算符\ + \; break;

// System.out.println(\

list += row + \ + cache[i] + \ + \保留字\ + \; break;

// System.out.println(\界符\

list += row + \ + cache[i] + \ + \界符\ + \; break;

// System.out.println(\常量\

list += row + \ + cache[i] + \ + \常量\ + \; break;

// System.out.println(\标识符\

list += row + \ + cache[i] + \ + \标识符\ + \; break;

// System.out.println(\格式不正确\

error += row + \ + cache[i] + \ + \格式不正确\ + \; count++; break;

// System.out.println(\不能以0开头\

error += row + \ + cache[i] + \ + \不能以0开头\ + \; count++; break;

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

default:

}

}

}

break;

JLabel lb = new JLabel(\是否需要将更改保存?\, JLabel.CENTER); setLayout(new BorderLayout()); setBackground(Color.WHITE); JPanel pl = new JPanel(); add(\, pl); add(\, lb);

pl.setLayout(new FlowLayout()); pl.setBackground(Color.LIGHT_GRAY); pl.add(ok); pl.add(no); pl.add(cancel);

ok.setBackground(Color.WHITE); no.setBackground(Color.WHITE); cancel.setBackground(Color.WHITE);

setBounds(450, 300, 250, 150); ok.addActionListener(this); no.addActionListener(this); cancel.addActionListener(this); setVisible(true);

}

public void actionPerformed(ActionEvent e) { if(e.getSource()==ok) { FrameView my = new FrameView(); my.saveFile();

}

if(e.getSource()==no) System.exit(0);

if(e.getSource()==cancel)

this.dispose(); }

}

AboutFile.java

package view;

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Frame; import java.awt.GridLayout;

import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent;

import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea;

public class AboutFile extends JDialog implements ActionListener{

public AboutFile(Frame parent,String title,Boolean k) {

super(parent,title,true);

addWindowListener(new WindowAdapter() {

JPanel pla = new JPanel(); JPanel plb = new JPanel();

JLabel lba = new JLabel(\感谢老师和各位队友的帮助\, JLabel.CENTER); JLabel lbb = new JLabel(\版权人:崔立志\, JLabel.CENTER); JLabel lbc = new JLabel(\出版日期:2014年\, JLabel.CENTER);

lba.setOpaque(true);

setLayout(new BorderLayout()); setBackground(Color.WHITE);

plb.setLayout(new GridLayout(3, 1)); plb.add(lba); plb.add(lbb); plb.add(lbc);

add(\, pla); add(\, plb);

JButton confirm = new JButton(\确定\);

public void windowClosing(WindowEvent we) { }

dispose();

});

}

}

pla.add(confirm);

JTextArea t=new JTextArea(); t.setEditable(false);

setBounds(490, 300, 250, 150); confirm.addActionListener(this); setVisible(true);

public void actionPerformed(ActionEvent e) { }

dispose();

Analysis.java

package operation;

public class Analysis {

String table1[] = { \, \, \, \, \, \, \, \,\,\ };// 运算符 String table2[] = { \, \, \, \, \,

\, \, \, \, \, \, \, \, \ ,\,\,\,\};// 保留字

\,

String table3[] = { \, \, \, \, \, \ };// 界符 String cache1[]; String cache[]; int row = 1;// 行标

int find = 0; int statue;

public String list = \; public String error = \;

public int count = 0;// 统计错误个数 public Analysis(String tastring) { }

// 将文本按行分割

text = tastring.split(\); String text[];

public void match() {

for (int h = 0; h < text.length; h++) { char[] ch = text[h].toCharArray(); int lenth = 0; int p = 0;

cache = new String[100];

String cache1[] = text[h].split(\);// 将字符串按符号分隔 ','))) {

','))) {

for (int i = 0; i < cache1.length; i++) { if (cache1[i].equals(\)) { lenth++;

if ((lenth < ch.length) && (ch[lenth] != ' ')

&& ((ch[lenth] == ';') || (ch[lenth] == ':')

|| (ch[lenth] == '=') || (ch[lenth] ==

cache[p++] = String.valueOf(ch[lenth]); lenth++; break; } else {

continue;

}

}

if (!cache1[i].equals(\)) { cache[p++] = cache1[i]; }

lenth += cache1[i].length(); for (; lenth < ch.length;) { if ((ch[lenth] != ' ') && ((ch[lenth] == ';') || (ch[lenth] == ':')

|| (ch[lenth] == '=') || (ch[lenth] ==

cache[p++] = String.valueOf(ch[lenth]); lenth++; break;

} else {

while (ch[lenth] == ' ') { lenth++;

}

if ((ch[lenth] == ';') || (ch[lenth] == '=') || (ch[lenth] == ':') || (ch[lenth] == ','))

;

else

}

}

}

break;

// 运算符

for (int i = 0; i < cache.length && i < p; i++) { for (int k = 0; k < table1.length; k++) { if (cache[i].equals(table1[k])) { statue = 1; find = 1; print(i); break;

}

}

// 保留字

for (int k = 0; k < table2.length; k++) { if (cache[i].equals(table2[k])) { statue = 2; find = 1; print(i); break;

}

}

// 界符

for (int k = 0; k < table3.length; k++) { if (cache[i].equals(table3[k])) { statue = 3; find = 1; print(i); break;

}

}

// 不在上面三个表中 nottable(i); find = 0;

} row++;

}

}

private void nottable(int i) { if (find == 0) { int judge = 0;

char temp[] = cache[i].toCharArray();

本文来源:https://www.bwwdw.com/article/tfg2.html

Top