编译原理实验代码
编译原理 C语言 词法分析 实验 源码

编译原理实验报告 词法分析
南京信息工程大学 计算机与软件学院 软件工程 2009 级 1 班 54andy1@ 一.实验目的
#region 负数 算数减 算数减并赋值 case ANSIC.Character.MinusSign:
break; #endregion
#region 算数乘 算数乘并赋值 case ANSIC.Character.Asterisk:
if (index + 1 < SourceLines[row].Length && SourceLines[row][index + 1] == '+') { Result.Add(new Token(TokenTypes.MultiplyAsign, row, index, 2, "*=")); index++;
word.Append(SourceLines[row][index]); index++; while (index<SourceLines[row].Length) { if (SourceLines[row][index] >= '0' && SourceLines[row][index] <= '9')
编译原理实验报告 词法分析 1 / 19
一开始做词法分析的时候,单纯做词法分析,没有考虑到语法分析,所以没有架构好,在要做语法分析的 时候找不到合适的接口,这是第一个教训。
【编译原理】词法分析(CC++源代码+实验报告)

【编译原理】词法分析(CC++源代码+实验报告)⽂章⽬录1 实验⽬的和内容1.1实验⽬的(1)根据 PL/0 语⾔的⽂法规范,编写PL/0语⾔的词法分析程序;或者调研词法分析程序的⾃动⽣成⼯具LEX或FLEX,设计并实现⼀个能够输出单词序列的词法分析器。
(2)通过设计调试词法分析程序,实现从源程序中分离出各种类型的单词;加深对课堂教学的理解;提⾼词法分析⽅法的实践能⼒。
(3)掌握从源程序⽂件中读取有效字符的⽅法和产⽣源程序的内部表⽰⽂件的⽅法。
(4)掌握词法分析的实现⽅法。
(5)上机调试编出的词法分析程序。
1.2实验内容根据PL/0语⾔的⽂法规范,编写PL/0语⾔的词法分析程序。
要求:(1)把词法分析器设计成⼀个独⽴⼀遍的过程。
(2)词法分析器的输出形式采⽤⼆元式序列,即:(单词种类, 单词的值)2 设计思想2.1单词种类及其正规式(1)基本字单词的值单词类型正规式rbegin beginsym begincall callsym callconst constsym constdo dosym doend endsym endif ifsym ifodd oddsym oddprocedure proceduresym procedureread readsym readthen thensym thenvar varsym varwhile whilesym whilewrite writesym write(2)标识符单词的值单词类型正规式r标识符ident(字母)(字母|数字)*(3)常数单词的值单词类型正规式r常数number(数字)(数字)*(4)运算符单词的值单词类型正规式r+plus+-minus-*times*/slash/=eql=<>neq<><lss<<=leq<=>gtr>>=geq>=:=becomes:=(5)界符单词的值单词类型正规式r(lparen()rparen),comma,;semicolon;.period.2.2 根据正规式构造NFA下⾯我们根据上述的正规式来构造该⽂法的NFA,如下图所⽰,其中状态0为初态,凡带双圈的状态均为终态,状态24是识别不出单词符号的出错情形,其他状态的识别情况如下图中右边的注释所⽰。
编译原理-代码

编译原理实验报告代码姓名:AAA 学号:2010******** 班级:软件工程****班实验一词法分析package bag1;/** 词法分字符处理:* 将送入的单个字符拼成单词,初步处理,只剩下标识符和关键字未处理* @version 0.5 2012-04-12* @author XiaoDeng*/import java.io.File;import java.io.IOException;class CharacterHandl implements CheckCharacter{//private static final int TWO = 2;//在本版本中不再需要private ReadData readData = null;private boolean hasNextWords = true;public CharacterHandl(File f) {readData = new ReadData(f);}public boolean isNumber(char c) {return c >= '0' && c <= '9';}public boolean isCharacter(char c) {return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';}public boolean isOperator(char c) {switch (c) {case '+':case '-':case '*':case '/':case '&':case '!':case '|':case '%':case '>':case '<':case '=':case '#':case '^':case '~':case ':':return true;}return false;}public boolean isOperator(String s) {return s.equals(">=") || s.equals("<=") || s.equals("+=")|| s.equals("-=") || s.equals("*=") || s.equals("/=")|| s.equals("%=") || s.equals("!=") || s.equals(":=")|| s.equals("^=") || s.equals("&=") || s.equals("|=")|| s.equals("<<") || s.equals(">>") || s.equals("++")|| s.equals("--") || s.equals("&&") || s.equals("||"); }public boolean isSeparator(char c) {switch (c) {case ',':case '.':case '{':case '}':case ';':case '(':case ')':case '[':case ']':return true;}return false;}public boolean isSpace(char c) {return c == ' ' || c == '\n';}public boolean hasNextWords() {return hasNextWords;}Words getNextWords() throws IOException {char c = ' ';String s = "";/** 在未到文件尾部的前提条件下,处理空字符,换行*/if (false == readData.hasNext()) {hasNextWords = false;return new Words(Words.ERROR);}while (readData.hasNext() && isSpace(c)) {c = readData.getNextChar();}/*** 是字母(A-Z,a-z,_)*/if (readData.hasNext() && isCharacter(c)) {do {s += c;c = readData.getNextChar();} while (isCharacter(c) || isNumber(c));// 只要第一个不是数字就行,所以现在不要紧了readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.STRING);}/*** 是数字(0-9)*/else if (readData.hasNext() && isNumber(c)) {do {s += c;c = readData.getNextChar();} while (isNumber(c)||c=='.');readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.NUMBER);}/** 是操作符+,-,*,/,++,--等等* 思路:对于符号c,如果是‘-’号,考虑接下来的是不是数字,是数字就一直加到s里面直到其不是数字,若接下来不是数字,考虑是* 操作符还是其他的,是操作符就加到s,再判断,是不是二元的,是就保存,不是,把刚刚加进去的删除,回设* 对于符号c,不是‘-’号,考虑是接下来的是操作符还是其他的,是操作符就加到s,再判断,是不是二元的,是就保存,不是,把刚刚加进去的删除,回设*/else if (readData.hasNext() && isOperator(c)) {s += c;if (c =='-') {// 负数c = readData.getNextChar();if (isNumber(c)) {while (isNumber(c)||c=='.') {s += c;c = readData.getNextChar();}readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.NUMBER);//这里一定不要写错了NUMBER }// ifelse if (isOperator(c)) {// 二元操作符情况:此时不必回设s += c;if(isOperator(s)){//组合之后是二元操作符return new Words(s, Words.OPERATOR);}else {//两个操作符组合起来不是二元操作符s=String.valueOf(s.toCharArray()[0]);readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.OPERATOR);}} else {//不是数字,不是操作符readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.OPERATOR);}}// if(c=='-')else {c = readData.getNextChar();if (isOperator(c)) {s += c;if(isOperator(s)){return new Words(s, Words.OPERATOR);}else {//两个操作符组合起来不是二元操作符s=String.valueOf(s.toCharArray()[0]);readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.OPERATOR);}} else {readData.setToPrevious();// 因为作为判断的那个字符应该算作没处理的的,标记往回设一位return new Words(s, Words.OPERATOR);}}//else}/** 是界符, ( ) { }等等*/else if (readData.hasNext() && isSeparator(c)) {s += c;// 不用设回标记return new Words(s, Words.SEPARATOR);}/** 无法识别的符号*/return new Words(Words.ERROR);}// getNextWord}package bag1;/** 对各种字符判断方法的接口* @version 0.5 2012-04-12* @author XiaoDeng*/abstract interface CheckCharacter {boolean isNumber(char c);boolean isCharacter(char c);boolean isOperator(char c);boolean isOperator(String s);boolean isSeparator(char c);boolean isSpace(char c);boolean hasNextWords();}package bag1;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import java.util.List;class ClassifyWords {CharacterHandl charHandl = null;List<String> keyWords = new ArrayList<String>();// 存入关键字(保留字)List<String> identifiers = new ArrayList<String>();// 存入标识符List<String> separator = new ArrayList<String>();// 存入分界符List<String> operator = new ArrayList<String>();// 存入运算符List<String> number = new ArrayList<String>();// 存入数private static final String LINEFEED="\r\n";static String akeyWords[] = { "begin", "call", "const", "do", "end", "if","odd", "procedure", "read", "then", "var", "while", "write" };// 保留字表String sK = "";//存储keyWords中遍历出来的内容,以下类似String sI = "";//注意不用null,因为null也会被写进去String sO = "";String sS = "";String sN = "";public ClassifyWords(File f) {charHandl = new CharacterHandl(f);}String getsK() {return sK;}String getsI() {return sI;}String getsO() {return sO;}String getsS() {return sS;}String getsN() {return sN;}List<String> getKeyWords() { return keyWords;}List<String> getIdentifiers() { return identifiers;}List<String> getSeparator() { return separator;}List<String> getOperator() { return operator;}List<String> getNumber() { return number;}void classify() {Words words=null;String getWords = null;while (charHandl.hasNextWords()) {try {words = charHandl.getNextWords();getWords = words.getWord();} catch (IOException e) {e.printStackTrace();}// System.out.println(words==null);switch (words.getID()) {case Words.STRING:if (isKeyWords(getWords)) {keyWords.add(getWords);} else {identifiers.add(getWords);}break;case Words.NUMBER:number.add(getWords);break;case Words.OPERATOR:operator.add(getWords);break;case Words.SEPARATOR:separator.add(getWords);break;case Words.ERROR:break;}// switch}// while}// classify/*** 将处理结果写到文件中去* 步骤:* 新建文件夹result-->建立keyWords,number,identifiers,operator,separator文本文件,并存储对应容器中的结果*/void writeIntoFile(){File storeFile=new File("result");if(false==storeFile.exists()){storeFile.mkdir();}try {FileWriter fw_keyWords=newFileWriter(storeFile.getPath()+File.separator+"keyWords.txt",false);FileWriter fw_identifiers=newFileWriter(storeFile.getPath()+File.separator+"identifiers.txt",false);FileWriter fw_operator=newFileWriter(storeFile.getPath()+File.separator+"operator.txt",false);FileWriter fw_separator=newFileWriter(storeFile.getPath()+File.separator+"separator.txt",false);FileWriter fw_number=newFileWriter(storeFile.getPath()+File.separator+"number.txt",false);BufferedWriter bfw_keyWords=new BufferedWriter(fw_keyWords);BufferedWriter bfw_identifiers=new BufferedWriter(fw_identifiers);BufferedWriter bfw_operator=new BufferedWriter(fw_operator);BufferedWriter bfw_separator=new BufferedWriter(fw_separator);BufferedWriter bfw_number=new BufferedWriter(fw_number);for (String s : keyWords)sK+=(s+LINEFEED);for (String s : identifiers)sI+=(s+LINEFEED);for (String s : number)sN+=(s+LINEFEED);for (String s : operator)sO+=(s+LINEFEED);for (String s : separator)sS+=(s+LINEFEED);bfw_keyWords.write(sK);bfw_identifiers.write(sI);bfw_operator.write(sO);bfw_separator.write(sS);bfw_number.write(sN);bfw_keyWords.close();bfw_identifiers.close();bfw_operator.close();bfw_separator.close();bfw_number.close();fw_keyWords.close();fw_identifiers.close();fw_operator.close();fw_separator.close();fw_number.close();} catch (IOException e) {e.printStackTrace();}}//writeIntoFile/*** 判断是否为关键字** @param s* @return 是保留字返回true否则返回false*/boolean isKeyWords(String words) {for (String s : akeyWords)if (words.equals(s))return true;return false;}/*public static void main(String[] args) throws IOException {ClassifyWords rea = new ClassifyWords(new File("资源"+File.separator+"测试.txt"));rea.classify();for (String s : rea.keyWords)System.out.println(s);for (String s : rea.identifiers)System.out.println(s);for (String s : rea.number)System.out.println(s);for (String s : rea.operator)System.out.println(s);for (String s : rea.separator)System.out.println(s);rea.writeIntoFile();}*/}// class结束package bag1;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;/** 读数据:只要知道一个File对象,便可以读书数据,返回单个字符* @version 0.5 2012-04-12* @author XiaoDeng*/class ReadData {private char data;//读到的数据private boolean isEnd;//是否结束private static final int TAG=100;//IO中mark用到的private BufferedInputStream bin;//流public ReadData(File f) {try {bin = new BufferedInputStream(new FileInputStream(f));} catch (FileNotFoundException e) {e.printStackTrace();}this.data = ' ';this.isEnd = false;}char getNextChar() throws IOException {int read = -1;bin.mark(TAG);if ((read = bin.read()) == -1) {isEnd = true;return ' ';} else {data = (char) read;return data;}}boolean hasNext() {return isEnd==false;}void setToPrevious() {try {bin.reset();} catch (IOException e) {e.printStackTrace();}}/* public static void main(String []args) throws IOException{ReadData rea=new ReadData(newFile("G:"+File.separator+"Users"+File.separator+"hp"+File.separator+"workspace"+File.separator +"词法分析"+File.separator+"资源"+File.separator+"测试.txt"));System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());rea.setToPrevious( );System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());System.out.println(rea.getNextChar());}*/}package bag1;/** 字符串+身份* @version 0.5 2012-04-12* @author XiaoDeng*/class Words {public static final int STRING=1;public static final int NUMBER=2;public static final int OPERATOR=3;public static final int SEPARATOR=4;public static final int ERROR=-1;private String word;private int ID;public Words(String s, int iD) {this.word = s;ID = iD;}public Words( int iD) {this.word = "Error:无法识别";ID = iD;}String getWord() {return word;}int getID() {return ID;}}package bag1;import java.awt.BorderLayout;import java.awt.Color;import java.awt.FlowLayout;import java.awt.Font;import java.awt.GridLayout;import java.awt.Image;import java.awt.Toolkit;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.MouseAdapter;import java.awt.event.MouseEvent;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.Date;import javax.swing.AbstractAction;import javax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.JFileChooser;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.JScrollPane;import javax.swing.JTextArea;import javax.swing.KeyStroke;import javax.swing.filechooser.FileFilter;import javax.swing.filechooser.FileView;import javax.swing.text.BadLocationException;/** 词法分析界面* @version 0.5 2012-04-12* @author XiaoDeng*/public class Notepad {private static final int X_START = 40;private static final int Y_START = 20;private static final int WIDTH = 1200;private static final int HEIGHT = 650;private static final String LINEFEED = "\r\n";// 换行private MyWindow window;private Image image;private JMenuBar menuBar;private JMenu menu_file;private JMenu menu_edit;private JMenu menu_check;private JMenu menu_look;private JMenu menu_help;private JPopupMenu popMenu = new JPopupMenu();private JMenuItem menuItem_file_save;private JMenuItem menuItem_file_open;private JMenuItem menuItem_file_saveas;private JMenuItem menuItem_file_print;private JMenuItem menuItem_file_exit;private JMenuItem menuItem_edit_cancel;private JMenuItem menuItem_edit_cut;private JMenuItem menuItem_edit_copy;private JMenuItem menuItem_edit_paste;private JMenuItem menuItem_edit_delete;private JMenuItem menuItem_edit_search;private JMenuItem menuItem_edit_replace;private JMenuItem menuItem_edit_selectAll;private JMenuItem menuItem_edit_searchNext; private JMenuItem menuItem_edit_goto;private JMenuItem menuItem_edit_time;private JMenuItem menuItem_menu_check;private JPanel jpanel_textArea;private JPanel jpanel_jtKINOS;private JPanel jpanel_window;private JScrollPane scrollPane;private JTextArea textArea;private JTextArea jtK;private JTextArea jtS;private JTextArea jtN;private JTextArea jtO;private JTextArea jtI;private JFileChooser chooser;private File f_words;// 传递给classifyWordsprivate ClassifyWords classifyWords;private boolean hasOpened = false;Clipboard clipboard = null;// 定义一个剪切板对象public Notepad() {image = Toolkit.getDefaultToolkit().createImage("资源" + File.separator + "图标012.png");window = new MyWindow("词法分析", image, X_START, Y_START, WIDTH, HEIGHT); clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();// 获得系统的剪切板menuBar = new JMenuBar();menu_file = new JMenu("文件(F)");menu_file.setMnemonic('F');menu_edit = new JMenu("编辑(E)");menu_edit.setMnemonic('E');menu_check = new JMenu("检测(C)");menu_check.setMnemonic('C');menu_look = new JMenu("查看(V)");menu_look.setMnemonic('V');menu_help = new JMenu("帮助(H)");menu_help.setMnemonic('H');// 添加菜单menuBar.add(menu_file);menuBar.add(menu_edit);menuBar.add(menu_check);menuBar.add(menu_look);menuBar.add(menu_help);// 添加文件菜单项menuItem_file_open = menu_file.add("打开");menuItem_file_open.setAccelerator(KeyStroke.getKeyStroke("ctrl+ o")); menuItem_file_save = menu_file.add("保存");// 菜单项独特的用法menuItem_file_save.setAccelerator(KeyStroke.getKeyStroke("ctrl+ s")); menuItem_file_saveas = menu_file.add("另存为");menu_file.addSeparator();menuItem_file_print = menu_file.add("打印");menuItem_file_exit = menu_file.add("退出");// 添加编辑菜单项menuItem_edit_cancel = menu_edit.add("取消");menuItem_edit_cut = menu_edit.add("剪切");menuItem_edit_copy = menu_edit.add("复制");menuItem_edit_paste = menu_edit.add("粘贴");menuItem_edit_delete = menu_edit.add("删除");menuItem_edit_search = menu_edit.add("查找");menuItem_edit_searchNext = menu_edit.add("查找下一个");menuItem_edit_replace = menu_edit.add("替换");menuItem_edit_goto = menu_edit.add("转到");menuItem_edit_selectAll = menu_edit.add("全选");menuItem_edit_time = menu_edit.add("时间" + File.separator + "日期");// 分析菜单项menuItem_menu_check = menu_check.add("词法分析");// 添加弹出菜单popMenu.add(menuItem_edit_cancel);popMenu.add(menuItem_edit_cut);popMenu.add(menuItem_edit_copy);popMenu.add(menuItem_edit_paste);popMenu.addSeparator();popMenu.add(menuItem_edit_delete);chooser = new JFileChooser();// 添加文本域jpanel_textArea = new JPanel();jpanel_jtKINOS = new JPanel();jpanel_window = new JPanel();textArea = new JTextArea();jtS = new JTextArea();jtN = new JTextArea();jtI = new JTextArea();jtO = new JTextArea();jtK = new JTextArea();jtS.setEditable(false);jtK.setEditable(false);jtN.setEditable(false);jtI.setEditable(false);jtO.setEditable(false);// textArea.setFont(new Font("Serif",14,Font.PLAIN ));//不能用,不知道为什么textArea.setEditable(true);textArea.setLineWrap(true);textArea.setWrapStyleWord(true);scrollPane = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);jpanel_textArea.setLayout(new BorderLayout());jpanel_textArea.add(scrollPane, BorderLayout.CENTER);JScrollPane scro_jtK = new JScrollPane(jtK,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane scro_jtN = new JScrollPane(jtN,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane scro_jtS = new JScrollPane(jtS,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane scro_jtO = new JScrollPane(jtO,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);JScrollPane scro_jtI = new JScrollPane(jtI,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);jpanel_jtKINOS.setLayout(new GridLayout(1, 6));jpanel_jtKINOS.add(scro_jtK);jpanel_jtKINOS.add(scro_jtI);jpanel_jtKINOS.add(scro_jtN);jpanel_jtKINOS.add(scro_jtO);jpanel_jtKINOS.add(scro_jtS);jpanel_window.setLayout(new GridLayout(2, 1));jpanel_window.add(jpanel_textArea);jpanel_window.add(jpanel_jtKINOS);window.add(jpanel_window);menuBar.setBackground(Color.cyan);window.setJMenuBar(menuBar);window.setVisible(true);TxtFileFilter txtFilter = new TxtFileFilter();JavaFileFilter javaFilter = new JavaFileFilter();chooser.addChoosableFileFilter(txtFilter);chooser.addChoosableFileFilter(javaFilter);chooser.setFileView(new FileIconView(txtFilter, new ImageIcon("资源"+ File.separator + "图标007.jpg")));chooser.setFileView(new FileIconView(javaFilter, new ImageIcon("资源"+ File.separator + "图标008.jpg")));addAllListener();}private void addAllListener() {// 打开menuItem_file_open.addActionListener(new AbstractAction() { private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {open();}// actionPerformed});// 保存menuItem_file_save.addActionListener(new AbstractAction() {private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {save();}// actionPerformed});// 另存为menuItem_file_saveas.addActionListener(new AbstractAction() {private static final long serialVersionUID = 1L;public void actionPerformed(ActionEvent e) {saveAs();}// actionPerformed});// 是文本域监听,不是popMenutextArea.addMouseListener(new MouseAdapter() {public void mouseReleased(MouseEvent e) {if (e.isPopupTrigger()) {popMenu.show(e.getComponent(), e.getPoint().x,e.getPoint().y);}}});menuItem_menu_check.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if (textArea.equals("")||f_words==null) {JOptionPane.showMessageDialog(textArea, "在进行此法检测前请先保存文件!", "警告",JOptionPane.WARNING_MESSAGE);}else if (false == hasOpened) {save();hasOpened = true;}if (hasOpened == true) {writeInFile(f_words);classifyWords = new ClassifyWords(f_words);classifyWords.classify();classifyWords.writeIntoFile();jtK.setText(classifyWords.getsK());jtK.append(LINEFEED + "共检索到"+ classifyWords.getKeyWords().size() + "条关键字");jtI.setText(classifyWords.getsI());jtI.append(LINEFEED + "共检索到"+ classifyWords.getIdentifiers().size() + "条标识符");jtN.setText(classifyWords.getsN());jtN.append(LINEFEED + "共检索到"+ classifyWords.getNumber().size() + "个数字");jtO.setText(classifyWords.getsO());jtO.append(LINEFEED + "共检索到"+ classifyWords.getOperator().size() + "个操作符");jtS.setText(classifyWords.getsS());jtS.append(LINEFEED + "共检索到"+ classifyWords.getSeparator().size() + "个关键字");}}});menuItem_file_exit.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {int result1;result1 = JOptionPane.showConfirmDialog(chooser, "确定将改动保存到"+ f_words.getAbsolutePath() + "?", "提示",JOptionPane.OK_CANCEL_OPTION);if (result1 == JOptionPane.OK_OPTION) {writeInFile(f_words);System.exit(0);} else {}}});menuItem_edit_time.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {textArea.insert((new Date()).toLocaleString(), 0);}});menuItem_edit_cut.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String temp = textArea.getSelectedText();// 获得鼠标拖动选取的文本StringSelection text = new StringSelection(temp);// 把待剪切的文本传递给// text 对象clipboard.setContents(text, null);// 将文本放入剪切板中int start = textArea.getSelectionStart();// 获取选中文本的开始位置int end = textArea.getSelectionEnd();// 获取选中文本的结束位置textArea.replaceRange("", start, end);// 选中的区域用""替换}});menuItem_edit_copy.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String temp = textArea.getSelectedText();// 获得鼠标拖动选取的文本StringSelection text = new StringSelection(temp);// 把待剪切的文本传递给// text 对象clipboard.setContents(text, null);// 将文本放入剪切板中}});menuItem_edit_delete.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String temp = textArea.getSelectedText();// 获得鼠标拖动选取的文本int start = textArea.getSelectionStart();int end = textArea.getSelectionEnd();textArea.replaceRange("", start, end);// 选中的区域用""替换}});menuItem_edit_paste.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {Transferable contexts = clipboard.getContents(this);// 获取剪切板中的内容DataFlavor flavor = DataFlavor.stringFlavor;// 剪切板的风格(系统的标准风格)if (contexts.isDataFlavorSupported(flavor))// 判断风格java是否可用{try {String str = (String) contexts.getTransferData(flavor);int n = textArea.getCaretPosition();// 获得文本中光标的位置textArea.replaceRange(str, n, n);// 替换光标所在位置的文本} catch (Exception ee) {}}}});menuItem_edit_selectAll.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {textArea.selectAll();}});}// addAllListenerprivate void writeInFile(File file) {String swrite = "";textArea.append("\0");for (int i = 0; i < textArea.getLineCount(); i++) {try {swrite += textArea.getText(textArea // getText(int offset,int// length).getLineStartOffset(i), textArea.getLineEndOffset(i)- textArea.getLineStartOffset(i) - 1);swrite += "\n";} catch (BadLocationException ex) {ex.printStackTrace();}}FileWriter fileWriter;try {fileWriter = new FileWriter(file, false);BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);bufferedWriter.write(swrite);bufferedWriter.close();fileWriter.close();} catch (IOException e) {e.printStackTrace();}}private void save() {chooser.setCurrentDirectory(new File("."));int result = chooser.showSaveDialog(window);int result1 = 0;if (result == JFileChooser.APPROVE_OPTION) {f_words = null;String fileTypeDescription = chooser.getFileFilter().getDescription();String fileType = null;String saveName = null;// 确定文件后缀名if (fileTypeDescription.equalsIgnoreCase("文本文件(*.txt)")) {int flag = chooser.getSelectedFile().getName().lastIndexOf(".");flag = (flag < 0 ? chooser.getSelectedFile().getName().length(): flag);// 第一次找不到的情况下flag为-1fileType = fileTypeDescription.substring(6, 10);saveName = chooser.getSelectedFile().getName().substring(0, flag)+ fileType;} else if (fileTypeDescription.equalsIgnoreCase("java源文件(*.java)")) {int flag = chooser.getSelectedFile().getName().lastIndexOf("."); // 第一次找不到的情况下flag为-1flag = (flag < 0 ? chooser.getSelectedFile().getName().length(): flag);fileType = fileTypeDescription.substring(9, 14);saveName = chooser.getSelectedFile().getName().substring(0, flag)+ fileType;}f_words = new File(chooser.getCurrentDirectory(), saveName);try {if (f_words.exists()) {result1 = JOptionPane.showConfirmDialog(chooser,"该文件已存在,确定要覆盖吗?", "提示",JOptionPane.OK_CANCEL_OPTION);if (result1 == JOptionPane.OK_OPTION) {// 有同名的文件,直接修改writeInFile(f_words);} else {// 什么也不做}} else {f_words.createNewFile();writeInFile(f_words);}if (result1 == JOptionPane.OK_OPTION) {// 能进行到这一步,说明信息保存成功,保存成功后,提示信息JOptionPane.showMessageDialog(chooser, "文件保存成功!", "提示",RMATION_MESSAGE);// 将信息清空fileTypeDescription = null;fileType = null;}} catch (FileNotFoundException fe) {JOptionPane.showMessageDialog(chooser, "在指定目录下没有找到文件!", "提示",RMATION_MESSAGE);} catch (IOException ie) {JOptionPane.showMessageDialog(chooser, "修改文件出错!", "提示",RMATION_MESSAGE);}}// if(result==JFileChooser.APPROVE_OPTION)}// saveprivate void saveAs() {chooser.setCurrentDirectory(new File("."));int result = chooser.showDialog(window, "另存为");int result1 = 0;if (result == JFileChooser.APPROVE_OPTION) {f_words = null;String fileTypeDescription = chooser.getFileFilter().getDescription();String fileType = null;String saveName = null;// 确定文件后缀名。
编译原理实验代码

for(i=0;i<l;i++)
for(j=0;j<N;j++)
{
//cout<<t[i].jihe[k]<<"->";
move(t[i],k,b); //求move(I,a)
//cout<<t[i].jihe[k]<<endl;
for(j=0;j<t[i].jihe[k].length();j++)
eclouse(t[i].jihe[k][j],t[i].jihe[k],b); //求e-clouse
if(b[k].change=="*")
{
if(he.find(b[k].last)>he.length())
he+=b[k].last;
eclouse(b[k].last[0],he,b);
}
}
}
void move(chan &he,int m,edge b[])
t[h++].ltab=t[i].jihe[j];
}
}
cout<<endl<<"状态转换矩阵如下:"<<endl;
outputfa(len,h,t); //输出状态转换矩阵
//状态重新命名
string *d=new string[h];
编译原理词法分析报告+代码(C语言版)[1]
![编译原理词法分析报告+代码(C语言版)[1]](https://img.taocdn.com/s3/m/637dba3cee06eff9aef807c3.png)
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
其中初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。
编译原理实验参考原代码

"Waiting for your expanding."
SCAN.C //词法分析器源程序
#include "globals.h" #include "scan.h"
void Do_Tag(char *strSource); void Do_Digit(char *strSource); void Do_EndOfTag(char *strSource); void Do_EndOfDigit(); void Do_EndOfEqual(char *strSource); void Do_EndOfPlus(char *strSource); void Do_EndOfSubtraction(char *strSource); void Do_EndOfMultiply(char *strSource); void Do_EndOfDivide(char *strSource); void Do_EndOfLParen(char *strSource); void Do_EndOfRParen(char *strSource); void Do_EndOfLeftBracket1(char *strSource); void Do_EndOfRightBracket1(char *strSource); void Do_EndOfLeftBracket2(char *strSource); void Do_EndOfRightBracket2(char *strSource); void Do_EndOfColon(char *strSource); void Do_EndOfComma(char *strSource); void Do_EndOfSemicolon(char *strSource); void Do_EndOfMore(char *strSource); void Do_EndOfLess(char *strSource); void Do_EndOfEnd(char *strSource); void Do_EndOfNEqual(char *strSource); void PrintError(int nColumn,int nRow,char chInput); void scaner(void);
编译原理实验报告——词法分析器(内含源代码)

编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
计算机编译原理实验报告

编译原理实验报告实验一词法分析设计一、实验功能:1、对输入的txt文件内的内容进行词法分析:2、由文件流输入test.txt中的内容,对文件中的各类字符进行词法分析3、打印出分析后的结果;二、程序结构描述:(源代码见附录)1、分别利用k[],s1[],s2[],s3[]构造关键字表,分界符表,算术运算符表和关系运算符表。
2、bool isletter(){} 用来判断其是否为字母,是则返回true,否则返回false;bool isdigit(){} 用来判断其是否为数字,是则返回true,否则返回false;bool iscalcu(){} 用来判断是否为算术运算符,是则返回true,否则返回false;bool reserve(string a[]){} 用来判断某字符是否在上述四个表中,是则返回true,否则返回false;void concat(){} 用来连接字符串;void getn(){} 用来读取字符;void getb(){} 用来对空格进行处理;void retract(){}某些必要的退格处理;int analysis(){} 对一个单词的单词种别进行具体判断;在主函数中用switch决定输出。
三、实验结果四、实验总结词法分析器一眼看上去很复杂,但深入的去做就会发现并没有一开始想象的那么困难。
对于一个字符的种别和类型可以用bool函数来判断,对于关键字和标示符的识别(尤其是3b)则费了一番功夫,最后对于常数的小数点问题处理更是麻烦。
另外,这个实验要设定好时候退格,否则将会导致字符漏读甚至造成字符重复读取。
我认为,这个实验在程序实现上大体不算困难,但在细节的处理上则需要好好地下功夫去想,否则最后的程序很可能会出现看上去没有问题,但实际上漏洞百出的状况。
将学过的知识应用到实际中并不简单,只有自己不断尝试将知识转化成程序才能避免眼高手低,对于知识的理解也必将更加深刻。
实验二LL(1)分析法一、实验原理:1、写出LL(1)分析法的思想:当一个文法满足LL(1)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[实验任务]完成以下正则文法所描述的Pascal语言子集单词符号的词法分析程序。
<标识符>→字母︱<标识符>字母︱<标识符>数字<无符号整数>→数字︱<无符号整数>数字<单字符分界符> →+ ︱-︱* ︱; ︱(︱)<双字符分界符>→<大于>=︱<小于>=︱<小于>>︱<冒号>=︱<斜竖>*<小于>→<<等于>→=<大于>→><冒号> →:<斜竖> →/该语言的保留字:begin end if then else for do while and or not 说明:1 该语言大小写不敏感。
2 字母为a-z A-Z,数字为0-9。
3可以对上述文法进行扩充和改造。
4 ‘/*……*/’为程序的注释部分。
[设计要求]1、给出各单词符号的类别编码。
2、词法分析程序应能发现输入串中的错误。
3、词法分析作为单独一遍编写,词法分析结果为二元式序列组成的中间文件。
4、设计两个测试用例(尽可能完备),并给出测试结果。
demo.cpp #include <stdio.h>#include <ctype.h>#include <string.h>#include "demo.h"char token[20];int lookup(char *token) {for (int i = 0; i < 11; i++) {if (strcmp(token, KEY_WORDS[i]) == 0) {return i+1;}}return 0;}char getletter(FILE *fp) {return tolower(fgetc(fp));}void out(FILE *fp, int c, char *value) {fprintf(fp, "%d,%s\n", c, value);}void report_error(FILE *fp, char ch) { fprintf(fp, "There must be some error.\n"); fprintf(fp, "%c...\n", ch);fprintf(fp, "^\n");}void scanner(FILE *infile, FILE *outfile) { char ch;int i, c;do {do {ch = getletter(infile);} while(isspace(ch));if (isalpha(ch)) {token[0] = ch;ch = getletter(infile);i = 1;while (isalnum(ch)) {token[i] = ch;i++;ch = getletter(infile);}token[i] = '\0';fseek(infile, -1, 1);c = lookup(token);if (c == 0) {out(outfile, ID, token);}else {out(outfile, c, " ");}}else {if (isdigit(ch)) {token[0] = ch;ch = getletter(infile);i = 1;while (isdigit(ch)) {token[i] = ch;i++;ch = getletter(infile);token[i] = '\0';fseek(infile, -1, 1);out(outfile, INT, token); }else {switch(ch) {case '<':{ch = getletter(infile);if (ch == '=') {out(outfile, LE, " ");}else if (ch == '>') {out(outfile, NE, " ");}else {fseek(infile, -1, 1);out(outfile, LT, " ");}break;}case '=':{out(outfile, EQ, " ");break;}case '>':{ch = getletter(infile);if (ch == '=') {out(outfile, GE, " ");}else {fseek(infile, -1, 1);out(outfile, GT, " ");}break;}case ':':{ch = getletter(infile);if (ch == '=') {out(outfile, FU, " ");else {fseek(infile, -1, 1);out(outfile, MAO, " "); }break;}case '/':{ch = getletter(infile);if (ch == '*') {out(outfile, ZHU, " "); }else {fseek(infile, -1, 1);out(outfile, XIE, " "); }break;}case '+':{out(outfile, JIA, " "); break;}case '-':{out(outfile, JIAN, " "); break;}case '*':{out(outfile, CHEN, " "); break;}case ';':{out(outfile, FEN, " "); break;}case '(':{out(outfile, ZUO, " "); break;}case ')':{out(outfile, YOU, " ");break;}default:{if (ch != EOF) {report_error(outfile, ch);}break;}}}}} while(ch != EOF);return;}void main() {FILE *in, *out;in = fopen("pascal.txt", "r");out = fopen("result.txt", "w");scanner(in, out);fprintf(out, "0,#");fclose(in);fclose(out);printf("Finished!\n");}本文来自CSDN博客,转载请标明出处:/ffee/archive/2006/05/31/766483.aspx[实验任务]1、实现LL(1)分析中控制程序(表驱动程序);2、完成以下描述算术表达式的LL(1)文法的LL(1)分析程序(LL(1)分析表见教材)。
E→TE′E′→ATE′|εT→FT′T′→MFT′|εF→(E)|iA→+|-M→*|/说明:终结符号i为用户定义的简单变量,即标识符的定义。
[设计要求]1、输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。
输出为输入串是否为该文法定义的算术表达式的判断结果。
2、LL(1)分析过程应能发现输入串出错。
3、设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。
demo.cpp #include <stdio.h>#include <string.h>#include <stdlib.h>#include "demo.h"#define SIZE 100char stack[SIZE];int bottom = 0, top = 0;void push(char ch) {if (top != SIZE) {stack[top] = ch;top++;}}char pop() {if (top != bottom) {top--;stack[top] = '\0';return stack[top];}return -2;}int get_id(FILE *fp) {char temp[100];fscanf(fp, "%d", &id);fgets(temp, 100, fp);return id;}void translate(int id, char *a) {switch(id) {case 0:*a = '#';break;case 12:*a = 'i';break;case 22:*a = '+';break;case 23:*a = '-';break;case 24:*a = '*';break;case 21:*a = '/';break;}}bool is_terminate(char ch) {if (ch == 'i' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '#') return true;return false;}void trans(char ch, char a, int *i, int *j) {switch (ch) {case 'E':*i = 0;break;case 'e':*i = 1;case 'T':*i = 2; break; case 't':*i = 3; break; case 'F':*i = 4; break; case 'A':*i = 5; break; case 'M': *i = 6; break;}switch (a) { case 'i':*j = 0; break; case '+':*j = 1; break; case '-':*j = 2; break; case '*':*j = 3; break; case '/':*j = 4; break; case '(':*j = 5; break; case ')':*j = 6; break; case '#':*j = 7; break;}}void search_table(char ch, char a) {int i, j;trans(ch, a, &i, &j);char temp[20] = {'\0'};strcpy(temp, TABLE[i][j]);if (strcmp(temp, "~") == 0) {pop();return;}else if (strcmp(temp, "") != 0) {pop();for (unsigned ii = 0; ii < strlen(temp); ii++) { push(temp[ii]);}return;}else {printf("Error!\n");exit(0);}}void main() {FILE *in;int id = 0;char a = 0;in = fopen("result.txt", "r");push('#');push('E');id = get_id(in);translate(id, &a);while (true) {if (is_terminate(stack[top-1])) {if (stack[top-1] == a && a == '#') {printf("success.\n");return;}else if (stack[top-1] == a) {pop();id = get_id(in);translate(id, &a);}else {printf("Error!\n");return;}}else if (!is_terminate(stack[top-1])) {search_table(stack[top-1], a);}}fclose(in);}本文来自CSDN博客,转载请标明出处:/ffee/archive/2006/05/31/766487.aspx[实验任务]完成以下描述算术表达式的LL(1)文法的递归下降分析程序G[E]:E→TE′E′→ATE′|εT→FT′T′→MFT′|εF→(E)|iA→+|-M→*|/说明:终结符号i为用户定义的简单变量,即标识符的定义。