编译原理实验代码
编译原理 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]
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求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)条件时,我们就可以为它构造一个不带回溯的自上而下的分析程序,这个分析程序是有一组递归过程组成的,每个过程对应文法的一个非终结符。
编译原理实验 (词法语法分析 附源代码
编译原理实验报告******************************************************************************* ******************************************************************************* PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而PL0语言的编译程序能充分体现一个高级语言编译程序实现的基本方法和技术。
PL/0语言文法的EBNF表示如下:<程序>::=<分程序>.<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句><常量说明> ::=CONST<常量定义>{,<常量定义>};<常量定义> ::=<标识符>=<无符号整数><无符号整数> ::= <数字>{<数字>}<变量说明> ::=V AR <标识符>{, <标识符>};<标识符> ::=<字母>{<字母>|<数字>}<过程说明> ::=<过程首部><分程序>{; <过程说明> };<过程首部> ::=PROCEDURE <标识符>;<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>|<复合语句>|<读语句><写语句>|<空><赋值语句> ::=<标识符>:=<表达式><复合语句> ::=BEGIN <语句> {;<语句> }END<条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式><表达式> ::= [+|-]<项>{<加法运算符> <项>}<项> ::= <因子>{<乘法运算符> <因子>}<因子> ::= <标识符>|<无符号整数>| ‘(’<表达式>‘)’<加法运算符> ::= +|-<乘法运算符> ::= *|/<关系运算符> ::= =|#|<|<=|>|>=<条件语句> ::= IF <条件> THEN <语句><过程调用语句> ::= CALL 标识符<当循环语句> ::= WHILE <条件> DO <语句><读语句> ::= READ‘(’<标识符>{,<标识符>}‘)’<写语句> ::= WRITE‘(’<表达式>{,<表达式>}‘)’<字母> ::= a|b|…|X|Y|Z<数字> ::= 0|1|…|8|9【预处理】对于一个pl0文法首先应该进行一定的预处理,提取左公因式,消除左递归(直接或间接),接着就可以根据所得的文法进行编写代码。
编译原理实验一代码
Scan.c#include"stdio.h"#include"ctype.h"#include"string.h"#include"tag.h"typedef enum{ENDF=1,ERROR=2,ID=3,NUM=4,RNUM=5,INT=6,REAL=7,MOD=8,ITOR=9, ADD=10,MUL=11,ASSIGN=12,SEMI=13,COMMA=14,LPAR=15,RPAR=16} Tag;#define MAXTOKENSIZE 9#define MAXCHILDERN 3typedef Tag TokenType;typedef Tag NodeKind;#endifint col,row;FILE *source;TokenType token;char tokenString[MAXTOKENSIZE];#define BUFSIZE 128static char buf[BUFSIZE]="\0";static char nextch(){if(col>=strlen(buf)){row++;if(fgets(buf,BUFSIZE-1,source)){col=0;return buf[col++];}return EOF;}return buf[col++];}static voi d retract(){col--;}#define MAXRESERVEWORDS 3struct {char* str;TokenType tok;}reserveword[MAXRESERVEWORDS]={ {"mod",MOD},{"int",INT},{"real",REAL}};static TokenType rsfind(char* s){int i;for(i=0;i<MAXRESERVEWORDS;i++) if(!strcmp(s,reserveword[i].str)){return reserveword[i].tok;}return ID;}static voi d id(char ch){int i=0;tokenString[i++]=ch;while(isalpha(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;retract();tokenString[i]='\0';token=rsfind(tokenString);if(token!=ID) tokenString[0]=0;}static voi d num(char ch){int i=0;tokenString[i++]=ch;while(isdigit(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;if(ch!='.'){retract();tokenString[i]='\0';token=NUM;}else{tokenString[i++]=ch;while(isdigit(ch=nextch()))if(i<MAXTOKENSIZE-1)tokenString[i++]=ch;retract();tokenString[i]='\0';token=RNUM;}}void tkget(){char ch;strcpy(tokenString,"\0");while(isspace(ch=nextch()));if(isdigit(ch)){num(ch);}else if(isalpha(ch)){id(ch);}else if(ch==EOF){token=ENDF;}else{switch(ch){case'+':token=ADD;break;case'*':token=MUL;break;case';':token=SEMI;break;case',':token=COMMA;break;case'(':token=LPAR;break;case')':token=RPAR;break;case'=':token=ASSIGN;break;default:token=ERROR;break;}}}#include"stdio.h"#include"tree.h"int main(int arge,char*argv[0]){ extern Tree root;extern File*source;source=fopen(argv[1],"r");root=(Tree)parse();trseq(root);trput(stdout,root);stput(stdout);}。
编译原理语法分析报告+代码
语法分析一、实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验要求利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
2.1 待分析的简单语言的语法用扩充的BNF表示如下:⑴<程序>::=begin<语句串>end⑵<语句串>::=<语句>{;<语句>}⑶<语句>::=<赋值语句>⑷<赋值语句>::=ID:=<表达式>⑸<表达式>::=<项>{+<项> | -<项>}⑹<项>::=<因子>{*<因子> | /<因子>⑺<因子>::=ID | NUM | (<表达式>)2.2 实验要求说明输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。
例如:输入begin a:=9; x:=2*3; b:=a+x end #输出success!输入x:=a+b*c end #输出error2.3 语法分析程序的酸法思想(1)主程序示意图如图2-1所示。
图2-1 语法分析主程序示意图(2)递归下降分析程序示意图如图2-2所示。
(3)语句串分析过程示意图如图2-3所示。
图2-3 语句串分析示意图图2-2 递归下降分析程序示意图(4)statement语句分析程序流程如图2-4、2-5、2-6、2-7所示。
图2-4 statement语句分析函数示意图图2-5 expression表达式分析函数示意图图2-7 factor分析过程示意图三、语法分析程序的C语言程序源代码:#include "stdio.h"#include "string.h"char prog[100],token[8],ch;char *rwtab[6]={"begin","if","then","while","do","end"};int syn,p,m,n,sum;int kk;factor();expression();yucu();term();statement();lrparser();scaner();main(){p=kk=0;printf("\nplease input a string (end with '#'): \n");do{ scanf("%c",&ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();getch();}lrparser(){if(syn==1){scaner(); /*读下一个单词符号*/yucu(); /*调用yucu()函数;*/if (syn==6){ scaner();if ((syn==0)&&(kk==0))printf("success!\n");}else { if(kk!=1) printf("the string haven't got a 'end'!\n");kk=1;}}else { printf("haven't got a 'begin'!\n");kk=1;}return;}yucu(){statement(); /*调用函数statement();*/while(syn==26){scaner(); /*读下一个单词符号*/if(syn!=6)statement(); /*调用函数statement();*/}return;}statement(){ if(syn==10){scaner(); /*读下一个单词符号*/if(syn==18){ scaner(); /*读下一个单词符号*/ expression(); /*调用函数statement();*/ }else { printf("the sing ':=' is wrong!\n");kk=1;}}else { printf("wrong sentence!\n");kk=1;}return;}expression(){ term();while((syn==13)||(syn==14)){ scaner(); /*读下一个单词符号*/ term(); /*调用函数term();*/}return;}term(){ factor();while((syn==15)||(syn==16)){ scaner(); /*读下一个单词符号*/ factor(); /*调用函数factor(); */ }return;}factor(){ if((syn==10)||(syn==11)) scaner();else if(syn==27){ scaner(); /*读下一个单词符号*/expression(); /*调用函数statement();*/ if(syn==28)scaner(); /*读下一个单词符号*/else { printf("the error on '('\n");kk=1;}}else { printf("the expression error!\n");kk=1;}return;}scaner(){ sum=0;for(m=0;m<8;m++)token[m++]=NULL;m=0;ch=prog[p++];while(ch==' ')ch=prog[p++];if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))){ while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) {token[m++]=ch;ch=prog[p++];}p--;syn=10;token[m++]='\0';for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}else if((ch>='0')&&(ch<='9')){ while((ch>='0')&&(ch<='9')){ sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else switch(ch){ case '<':m=0;ch=prog[p++];if(ch=='>'){ syn=21;}else if(ch=='='){ syn=22;}else{ syn=20;p--;}break;case '>':m=0;ch=prog[p++];if(ch=='='){ syn=24;}else{ syn=23;p--;}break;case ':':m=0;ch=prog[p++];if(ch=='='){ syn=18;}else{ syn=17;p--;}break;case '+': syn=13; break;case '-': syn=14; break;case '*': syn=15;break;case '/': syn=16;break;case '(': syn=27;break;case ')': syn=28;break;case '=': syn=25;break;case ';': syn=26;break;case '#': syn=0;break;default: syn=-1;break;}}四、结果分析:输入begin a:=9; x:=2*3; b:=a+x end # 后输出success!如图4-1所示:图4-1输入x:=a+b*c end # 后输出error 如图4-2所示:图4-2五、总结:通过本次试验,了解了语法分析的运行过程,主程序大致流程为:“置初值”→调用scaner 函数读下一个单词符号→调用IrParse→结束。
(完整word版)PL0源程序-编译原理实验代码
附件1 小组成员:程序清单Main.c#include<stdio.h>#include<stdlib.h>#include<string.h>void error(int n);void getsym();//void enter(enum object k,int *ptx,int lev,int *pdx);int position(char*idt,int tx);int constdeclaration(int *ptx,int lev,int *pdx);int vardeclaration(int *ptx,int lev,int *pdx);int factor(int*ptx,int lev);int term(int *ptx,int lev);int expression(int *ptx,int lev);int statement(int *ptx,int lev);int block();enum object{constant,variable,procedure};struct tab{char name[14];enum object kind;int val;int level;int adr;int size;}table[100];enum symbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,r paren,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,ca llsym,constsym,varsym,procsym,progsym,};enum symbol sym=nul;enum symbol mulop;enum symbol wsym[14];enum symbol ssym[256];char ch=' ';char *str;charword[14][10]={"begin","call","const","do","end","if","odd","procedure","program ","read","then","var","while","write"};//设置保留字名字int num;int lev=0;int tx=0;int k;int *mm;//=(int *)malloc(sizeof(int));char *id,sign[14];char a[14];FILE *fp1,*fp2,*fp3;void error(int n){switch(n){case 1:printf("常数说明中的\"=\"写成了\":=\"。
编译原理--词法分析实验(含代码)备课讲稿
编译原理--词法分析实验(含代码)计算机编译原理实验班级:计算机科学与技术113班姓名:学号:南昌大学信息工程学院计算机系实验1 词法分析程序的设计一、实验目的掌握计算机语言的词法分析程序的开发方法。
二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求1、根据以下的正规式,编制正规文法,画出状态图;标识符<字母>(<字母>|<数字字符>)*十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*如有余力,则进一步分析八进制和十六进制整数,其正规式如下:八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和界符+ - * / > < = <= >= ( ) ; { }关键字main if then else while do int (可根据需要添加)2、根据状态图,设计词法分析函数int scan( ),完成以下功能:1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,2)以二元式形式输出单词<单词种类,单词属性>其中单词种类用整数表示:0:标识符1:十进制整数2:八进制整数3:十六进制整数运算符和界符,关键字采用一字一符,不编码其中单词属性表示如下:标识符,整数由于采用一类一符,属性用单词表示运算符和界符,关键字采用一字一符,属性为空3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。
四、实验环境PC微机DOS操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual C++ 程序集成环境五、实验步骤1、根据正规式,画出状态转换图;2、根据状态图,设计词法分析算法;3、采用C或C++语言,设计函数scan( ),实现该算法;4、编制测试程序(主函数main);5、调试程序:读入文本文件program.txt,运行程序得到输出结果result.txt,并检查输出结果是否正确。
编译原理实验2源代码
{-1,-1,-1,106,-1,9,10,106,-1,-1,-1},
{-1,-1,-1,108,-1,9,10,108,-1,-1,-1}};
/********************从文件读一行到缓冲区**********************/
sstack[100],
ibuf[100],
stack[1000];
struct aa oth;
struct fourexp
{
char op[10];
struct aa arg1;
struct aa arg2;
int result;
}fexp[200];
{-1,106,106,106,106,-1,106,106,-1},};
/********************布尔表达式的LR分析表*********************/
static int action2[16][11]=
{{1,-1,4,-1,5,-1,-1,-1,13,7,8},
/***********************标识符和关键字的识别********************/
find(char spel[])
{
int ss1=0;
int ii=0;
while((ss1==0)&&(ii<nlength))
{
if(!strcmp(spel,ntab1[ii]))
#define S 11
#define L 12
#define tempsy 15
编译原理实验 编译器 综合报告(附源代码)
编译原理编译器综合实验---------------工程精品神刀公子一.实验背景编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程序。
一个现代编译器的主要工作流程:源代码(source code) →预处理器(preprocessor) →编译器 (compiler) →目标代码(object code) →链接器(Linker) → 可执行程序 (executables)高级计算机语言便于人编写,阅读交流,维护。
机器语言是计算机能直接解读、运行的。
编译器将汇编或高级计算机语言源程序(Source program)作为输入,翻译成目标语言(Target language)机器代码的等价程序。
源代码一般为高级语言(High-level language),如Pascal、C、C++、Java、汉语编程等或汇编语言,而目标则是机器语言的目标代码(Object code),有时也称作机器代码(Machine code)。
对于C#、VB等高级语言而言,此时编译器完成的功能是把源码(SourceCode)编译成通用中间语言(MSIL/CIL)的字节码(ByteCode)。
最后运行的时候通过通用语言运行库的转换,编程最终可以被CPU直接计算的机器码(NativeCode)。
二.算法设计典型的编译器输出是由包含入口点的名字和地址,以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。
一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的EXE,词法分析程序→语法分析程序→语义分析程序→编译器。
不断完善,不断改进。
渐变的过程。
函数。
void scanner(); //扫描void lrparser();void staBlock(int *nChain); //语句块void staString(int *nChain); //语句串void sta(int *nChain); //语句void fuzhi(); //赋值语句void tiaojian(int *nChain); //条件语句void xunhuan(); //循环语句char* E(); //Expresiion表达式char* T(); //Term项char* F(); //Factor因子char *newTemp(); //自动生成临时变量void backpatch(int p,int t); //回填int merge(int p1,int p2); //合并p1和p2void emit(char *res,char *num1,char *op,char *num2); //生成四元式截图说明:综合输入:(赋值,循环,条件。
编译原理教程实验报告
一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。
二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。
2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。
3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。
4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。
5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。
6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。
四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。
2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。
3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。
4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。
5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。
6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。
五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。
编译原理中实验报告
实验名称:编译原理实验实验时间:2023年X月X日实验地点:实验室实验指导老师:XXX一、实验目的1. 理解编译原理的基本概念和流程。
2. 掌握词法分析和语法分析的基本方法。
3. 学习编译器生成中间代码和目标代码的过程。
4. 培养编程能力和问题解决能力。
二、实验内容本次实验主要包括以下内容:1. 词法分析:编写一个简单的词法分析器,将源代码输入转换为抽象语法树(AST)。
2. 语法分析:实现一个简单的递归下降解析器,对词法分析器输出的AST进行语法分析。
3. 中间代码生成:根据AST生成三地址代码(Three-Address Code)。
4. 代码优化:对生成的三地址代码进行优化。
5. 目标代码生成:将优化后的三地址代码转换为机器代码。
三、实验步骤1. 设计词法分析器首先,我们需要设计一个能够识别源代码中各种单词的词法分析器。
在本实验中,我们定义了以下几种单词:- 关键字:如if、else、while、int、float等。
- 标识符:由字母、数字和下划线组成,不能以数字开头。
- 常量:包括整型常量和浮点型常量。
- 运算符:如+、-、、/、==、<=等。
- 分隔符:如(、)、;、,等。
根据以上定义,我们可以编写一个词法分析器,它将输入的源代码字符串逐个字符地读取,并根据定义的规则识别出相应的单词。
2. 语法分析词法分析器生成的AST是一个树形结构,其中每个节点代表源代码中的一个单词或符号。
为了进一步分析AST的结构,我们需要实现一个递归下降解析器,它能够根据语法规则对AST进行解析。
在本实验中,我们以一个简单的算术表达式为例,实现了一个递归下降解析器。
解析器从AST的根节点开始,按照语法规则递归地解析每个子节点,直到整个表达式被解析完毕。
3. 中间代码生成在完成语法分析后,我们需要将AST转换为中间代码。
在本实验中,我们选择了三地址代码作为中间代码的形式。
三地址代码是一种表示赋值、条件判断和循环等操作的方式,它使用三个操作数和两个操作符来表示一个操作。
编译原理综合性实验报告-分析中间代码生成程序分析
编译原理综合性实验报告-分析中间代码⽣成程序分析编译原理综合性实验报告-分析中间代码⽣成程序分析XXXXXX计算机系综合性实验实验报告课程名称编译原理实验学期 XXXX ⾄ XXXX 学年第 X 学期学⽣所在系部计算机系年级 X 专业班级 XXXXXX 学⽣姓名 XXX学号 XXXXXXXXXXXX 任课教师XXX 实验成绩计算机系制《编译原理》课程综合性实验报告开课实验室: 年⽉⽇实验题⽬分析中间代码⽣成程序⼀、实验⽬的分析PL/0编译程序的总体结构、代码⽣成的⽅法和过程;具体写出⼀条语句的中间代码⽣成过程。
⼆、设备与环境PC兼容机、Windows操作系统、Turbo Pascal软件等。
三、实验内容1. 分析PL/0程序的Block⼦程序,理清PL/0程序结构和语句格式。
画出Block⼦程序的流程图,写出⾄少两条PL/0程序语句的语法格式。
2. 分析PL/0程序的Block⼦程序和Gen⼦程序,了解代码⽣成的⽅法和过程。
使⽤概要算法来描述语句的代码⽣成过程。
3. ⾃⼰编写⼀个简单的PL/0程序,能够正确通过编译,得到中间代码。
列出⾃⼰编写的源程序和编译后得到的中间代码。
4. 从中选择⼀个语句或表达式,写出代码⽣成的过程。
要求从⾃⼰的源程序中选择⼀条语句,结合这条语句写出语义分析和代码⽣成过程。
在描述这个过程中,要说清楚每个功能有哪个⼦程序的哪条语句来完成,说清楚语句和参数的含义和功能。
四、实验结果及分析(⼀)Block⼦程序分析1.常量声明的分析:常量声明部分的语法结构定义为如下形式:-> const ;-> [;]->id = C其中C可以是常量标识符或字符串或整数(可带符号)或实数(可带符号)。
常量声明分析程序的主要任务是:(1).扫描整个常量声明部分。
(2).为被声明的常量标识符建⽴符号表项。
(3).检查重复的声明。
2.变量声明部分的分析:变量声明部分的语法结构定义为如下形式:-> var-> [;]->:T->id[,]其中idList是被定义的变量标识符序列,T是类型表达式。
编译原理_LL(1)文法源代码(实验三)
一、实验目的及要求1.把握LL(1)分析法的大体原理;2.把握LL(1)分析表的构造方式;3.用LL(1)分析法分析高级语言表达式。
4、了解LL(1)分析器的工作进程。
文法:无二义性的算术表达式的文法(1)把词法分析作为语法分析的子程序实现(5分)(2)独立的语法分析程序(4分)(3)对表达式文法排除左递归、构造LL(1)分析表(4)LL(1)分析表能够直接输入(4分),也能够用程序实现(5分)(5)给一个表达式,给出分析进程(分析栈、输入串、所用规那么)(4分)(6)生成一个棵语法树(5分)用二叉树的形式表示出来二、实验内容及原理一、实验原理(1)、LL(1)文法的概念LL(1)分析法属于确信的自顶向下分析方式。
LL(1)的含义是:第一个L说明自顶向下分析是从左向右扫描输入串,第2个L说明分析进程中将利用最左推导,1说明只需向右看一个符号即可决定如何推导,即选择哪个产生式(规那么)进行推导。
LL(1)文法的判别需要依次计算FIRST集、FOLLOW集和SELLECT集,然后判定是不是为LL(1)文法,最后再进行句子分析。
需要预测分析器对所给句型进行识别。
即在LL(1)分析法中,每当在符号栈的栈顶显现非终极符时,要预测用哪个产生式的右部去替换该非终极符;当显现终结符时,判定其与剩余输入串的第一个字符是不是匹配,若是匹配,那么继续分析,不然报错。
LL(1)分析方式要求文法知足如下条件:关于任一非终极符A的两个不同产生式A→α,A→β,都要知足下面条件:SELECT(A→α)∩SELECT(A→β)=∅(2)、预测分析表构造LL(1)分析表的作用是对当前非终极符和输入符号确信应该选择用哪个产生式进行推导。
它的行对应文法的非终极符,列对应终极符,表中的值有两种:一是产生式的右部的字符串,一是null。
假设用M表示LL(1)分析表,那么M可表示如下:M: VN×VT→P∪{Error}M(A, t) = A→α,当t∈select(A→α) ,不然M(A, t) = Error其中P表示所有产生式的集合。
- 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为用户定义的简单变量,即标识符的定义。