编译原理词法分析器java

合集下载

编译原理语法分析器(java完美运行版)

编译原理语法分析器(java完美运行版)

编译原理语法分析器(java完美运行版)第一篇:编译原理语法分析器 (java完美运行版)实验二语法分析器一、实验目的通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。

使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练学生掌握开发应用程序的基本方法。

有利于提高学生的专业素质,为培养适应社会多方面需要的能力。

二、实验内容υ根据某一文法编制调试 LL(1)分析程序,以便对任意输入的符号串进行分析。

υ构造预测分析表,并利用分析表和一个栈来实现对上述程序设计语言的分析程序。

υ分析法的功能是利用LL(1)控制程序根据显示栈栈顶内容、向前看符号以及LL(1)分析表,对输入符号串自上而下的分析过程。

三、LL(1)分析法实验设计思想及算法υ模块结构:(1)定义部分:定义常量、变量、数据结构。

(2)初始化:设立LL(1)分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等);(3)控制部分:从键盘输入一个表达式符号串;(4)利用LL(1)分析算法进行表达式处理:根据LL(1)分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。

四、实验要求1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、如果遇到错误的表达式,应输出错误提示信息。

3、对下列文法,用LL(1)分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i 输出的格式如下:五、实验源程序LL1.java import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.table.DefaultTableModel;import java.sql.*;import java.util.Vector;public class LL1 extends JFrame implements ActionListener { /****/private static final long serialVersionUID = 1L;JTextField tf1;JTextField tf2;JLabel l;JButton b0;JPanel p1,p2,p3;JTextArea t1,t2,t3;JButton b1,b2,b3;JLabel l0,l1,l2,l3,l4;JTable table;Statement sta;Connection conn;ResultSet rs;DefaultTableModel dtm;String Vn[]=null;Vector P=null;int firstComplete[]=null;//存储已判断过first的数据char first[][]=null;//存储最后first结果int followComplete[]=null;//存储已判断过follow的数据char follow[][]=null;//存储最后follow结果char select[][]=null;//存储最后select结果int LL=0;//标记是否为LL(1)String vt_tou[]=null;//储存VtObject shuju[][]=null;//存储表达式数据char yn_null[]=null;//存储能否推出空LL1(){ setLocation(100,0);setSize(700,780);tf1=new JTextField(13);tf2=new JTextField(13);l=new JLabel(“>>”);l0=new JLabel(“输入字符串:”);l1=new JLabel(“输入的文法”);l2=new JLabel(“ ”);l3=new JLabel(“分析的结”);l4=new JLabel(“预测分析”);//p1=new JPanel();p2=new JPanel();p3=new JPanel();t1=new JTextArea(24,20);t2=new JTextArea(1,30);t3=new JTextArea(24,40);b0=new JButton(“确定(S为开始)”);b1=new JButton(“ 判断文法”);为:果:表:b2=new JButton(“输入”);b3=new JButton(“清空”);table=new JTable();JScrollPane jp1=new JScrollPane(t1);JScrollPane jp2=new JScrollPane(t2);JScrollPane jp3=new JScrollPane(t3);p2.add(tf1);p2.add(l);p2.add(tf2);p2.add(b0);p2.add(b1);p2.add(l0);p2.add(l2);p2.add(jp2);p2. add(b2);p2.add(b3);p2.add(l1);p2.add(l3);p2.add(jp1);p2.add(jp3);p3.add(l4);p3.add(newJScrollPane(table));add(p2,“Center”);add(p3,“South”);b0.addActionListener(this);b1.addActionListener(this);b2.ad dActionListener(this);b3.addActionListener(this);setDefaultClose Operation(JFrame.EXIT_ON_CLOSE);table.setPreferredScrollable ViewportSize(new Dimension(660,200));setVisible(true);} public void actionPerformed(ActionEvent e){ if(e.getSource()==b0){ String a=tf1.getText();String b=tf2.getText();t1.append(a+'→'+b+'n');}if(e.getSource()==b1){ t3.setText(“");int Vnnum=0,k;Vn=new String[100];P=new Vector();String s[]=t1.getText().split(”n“);for(int i=0;ireturn;}if(s[i].charAt(0)<='Z'&&s[i].charAt(0)>='A'&&s[i].charAt(1)=='→'){ for(k=0;k=Vnnum){ Vn[Vnnum]=s[i].substring(0, 1);//存入Vn数据 Vnnum++;} P.add(s[i]);} else { t3.setText(”文法输入有误,请重新输入“);return;} } yn_null=new char[100];first=new char[Vnnum][100];int flag=0;String firstVn[]=null;firstComplete=new int[Vnnum];for(int i=0;Vn[i]!=null;i++)//依次求FIRST** { flag=0;firstVn=new String[20];if((flag=add_First(first[i],Vn[i],firstVn,flag))==-1)return;firstComplete[i]=1;} t3.append(”first集:“+”n“);//显示FIRST**for(inti=0;Vn[i]!=null;i++){ t3.append(”first(“+Vn[i]+”)={ “);for(int j=0;first[i][j]!='';j++){ t3.append(first[i][j]+” , “);} t3.append(”}“+”n“);}follow=new char[Vnnum][100];String followVn[]=null;followComplete=new int[Vnnum];for(int i=0;Vn[i]!=null;i++)//求FOLLOW** { flag=0;followVn=new String[20];if((flag=tianjiaFollow(follow[i],Vn[i],followVn,flag))==-1)return;followComplete[i]=1;} t3.append(”fol low集:“+”n“);//显示FOLLOW**for(inti=0;Vn[i]!=null;i++){ t3.append(”follow(“+Vn[i]+”)={ “);for(i nt j=0;follow[i][j]!='';j++){ t3.append(follow[i][j]+” , “);} t3.append(”}“+”n“);} select=new char[P.size()][100];for(int i=0;itianjiaSelect(select[i],(String)P.elementAt(i),flag);}t3.append(”select集:“+”n“);//显示SELECT**for(int i=0;ifor(int i=0;Vn[i]!=null;i++)//判断select交集是否为空{ intbiaozhi=0;char save[]=new char[100];for(int j=0;jif(t.substring(0,1).equals(Vn[i])){ for(k=0;select[j][k]!='';k++){ if(puanduanChar(save,select[j][k])){ save[biaozhi]=select[j][k];bia ozhi++;} else//当有交集时,不为LL(1)文法{ t3.append(”不是LL(1)文法!“+”n“);return;} } } } } char Vt[]=new char[100];int biaozhi=0;for(int i=0;i{ if(t.charAt(j)>'Z'||t.charAt(j)<'A'){ if(puanduanChar(Vt,t.cha rAt(j))){ Vt[biaozhi]=t.charAt(j);biaozhi++;} } } } if(puanduanChar(Vt,'#'))//若可推出空集,则将#加入Vt。

编译器编译原理详解

编译器编译原理详解

编译器编译原理详解编译器是一种将源代码转换为目标代码的程序。

它的作用是将人类可读的源代码翻译成计算机可执行的目标代码。

编译器的编译原理是一门关于如何设计和实现编译器的研究领域。

下面详细介绍编译器的编译原理。

编译器的编译原理主要包括以下几个部分:词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成。

词法分析是编译器的第一步,它将源代码分解成一系列的词法单元。

词法单元是编译器的最小处理单位,比如关键字、标识符、运算符和常数等。

词法分析器通常通过正则表达式来识别这些词法单元,然后生成一个词法分析表,用于语法分析。

语法分析是编译器的第二步,它根据词法分析器生成的词法单元序列,将其组合成抽象语法树。

抽象语法树是一种以树状结构表示源代码语法结构的数据结构。

语法分析使用的主要技术是上下文无关文法和语法分析算法,如LL算法和LR算法等。

语义分析是编译器的第三步,它主要负责对抽象语法树进行语义检查和类型推导。

语义检查是验证源代码是否符合语言规范的过程,比如检查变量是否定义、函数调用是否正确等。

类型推导是确定表达式的类型的过程,比如确定算术表达式的结果类型。

中间代码生成是编译器的第四步,它将抽象语法树转换成一种中间表示形式,通常是三地址代码或类似的形式。

中间代码是一种与具体机器无关的代码表示形式,它可以简化后续的代码优化和目标代码生成。

代码优化是编译器的第五步,它对中间代码进行优化,以提高目标代码的执行效率和空间利用率。

代码优化可以包括常量折叠、公共子表达式消除、循环不变表达式移动等优化技术。

目标代码生成是编译器的最后一步,它将中间代码转换成目标机器的机器代码。

目标代码生成主要包括指令选择、寄存器分配和代码布局等过程。

指令选择将中间代码转换成目标机器的指令序列,寄存器分配将临时变量分配到目标机器的寄存器或内存位置,代码布局将指令按照一定的顺序排列,以提高指令的缓存命中率。

综上所述,编译器的编译原理涉及词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等几个主要部分。

编译原理龙书第四章答案

编译原理龙书第四章答案

编译原理龙书第四章答案编译原理是计算机科学中的一门基础课程,是用于教授计算机程序的设计、构建和优化的学科,常常被用于编写编译器和解释器。

在编译原理课程中,龙书(Compilers: Principles, Techniques, and Tools)是一本经典的教材,其中第四章主要讲述了词法分析器的设计和实现。

以下是第四章的答案,按照列表划分:1. 什么是词法分析器?词法分析器(Lexical Analyzer)是编译器的组成部分之一,它用于将程序中的字符序列转换为一系列单词或词法单元(Lexeme),以便后续的语法分析和语义分析使用。

2. 词法分析器的工作流程是什么?词法分析器的工作流程如下:(1)读入字符序列。

(2)将字符序列划分为一个个词法单元,或者检查字符序列是否合法。

(3)生成一个词法单元序列,并将其传递给语法分析器。

3. 词法单元的定义是什么?词法单元是编程语言中的一个基本单元,它是对代码中的一个单一概念进行编码的基本方式。

例如,在C语言中,词法单元包括关键字(如int,if,while等)、标识符(Identifier,即自定义变量名)、运算符和特殊符号等。

4. 有哪些方法可以实现词法分析器?可以使用正则表达式、自动机等方法实现词法分析器。

其中,正则表达式可以表示字符串的集合,因此可以将其用于识别单词类别;自动机是根据输入字符序列转换状态的一种计算模型,因此可以用于实现有限自动机(Deterministic Finite Automaton)和非确定有限自动机(Nondeterministic Finite Automaton)等。

5. DFA和NFA分别是什么?DFA和NFA都是有限自动机的一种,但在转换动作上有所不同。

DFA 是确定的有限自动机,即在状态转换时只有唯一的一个选择;而NFA 是非确定的有限自动机,即在状态转换时可以有多个选择。

6. DFA和NFA之间有什么关系?DFA和NFA虽然在转换动作上不同,但它们可以互相转化。

编译原理LL(1)文法分析器实验(java)

编译原理LL(1)文法分析器实验(java)

编译原理LL(1)文法分析器实验本程序是基于已构建好的某一个语法的预测分析表来对用户的输入字符串进行分析,判断输入的字符串是否属于该文法的句子。

基本实现思想:接收用户输入的字符串(字符串以“#”表示结束)后,对用做分析栈的一维数组和存放分析表的二维数组进行初始化。

然后取出分析栈的栈顶字符,判断是否为终结符,若为终结符则判断是否为“#”且与当前输入符号一样,若是则语法分析结束,输入的字符串为文法的一个句子,否则出错若不为“#”且与当前输入符号一样则将栈顶符号出栈,当前输入符号从输入字符串中除去,进入下一个字符的分析。

若不为“#”且不与当前输入符号一样,则出错。

若栈顶符号为非终结符时,查看预测分析表,看栈顶符号和当前输入符号是否构成产生式,若产生式的右部为ε,则将栈顶符号出栈,取出栈顶符号进入下一个字符的分析。

若不为ε,将产生式的右部逆序的入栈,取出栈顶符号进入下一步分析。

程序流程图:本程序中使用以下文法作对用户输入的字符串进行分析:E→TE’E’→+TE’|εT→FT’T’→*FT’|εF→i|(E)该文法的预测分析表为:1、显示预测分析表,提示用户输入字符串2、输入的字符串为正确的句子:3、输入的字符串中包含了不属于终结符集的字符4、输入的字符串不是该文法能推导出来的句子程序代码:package ;import java.io.*;public class LL {String Vn[] = { "E", "E'", "T", "T'", "F" }; // 非终结符集String Vt[] = { "i", "+", "*", "(", ")", "#" }; // 终结符集String P[][] = new String[5][6]; // 预测分析表String fenxi[] ; // 分析栈int count = 1; // 步骤int count1 = 1;//’分析栈指针int count2 = 0, count3 = 0;//预测分析表指针String inputString = ""; // 输入的字符串boolean flag;public void setCount(int count, int count1, int count2, int count3){this.count = count;this.count1 = count1;this.count2 = count2;this.count3 = count3;flag = false;}public void setFenxi() { // 初始化分析栈fenxi = new String[20];fenxi[0] = "#";fenxi[1] = "E";}public void setP() { // 初始化预测分析表for (int i = 0; i < 5; i++) {for (int j = 0; j < 6; j++) {P[i][j] = "error";}}P[0][0] = "->TE'";P[0][3] = "->TE'";P[1][1] = "->+TE'";P[1][4] = "->ε";P[1][5] = "->ε";P[2][0] = "->FT'";P[2][3] = "->FT'";P[3][1] = "->ε";P[3][2] = "->*FT'";P[3][4] = "->ε";P[3][5] = "->ε";P[4][0] = "->i";P[4][3] = "->(E)";// 打印出预测分析表System.out.println(" 已构建好的预测分析表");System.out.println("----------------------------------------------------------------------");for (int i=0; i<6; i++) {System.out.print(" "+Vt[i]);}System.out.println();System.out.println("----------------------------------------------------------------------");for (int i=0; i<5; i++) {System.out.print(" "+Vn[i]+" ");for (int j=0; j<6; j++) {int l = 0;if (j>0) {l = 10-P[i][j-1].length();}for (int k=0; k<l; k++) {System.out.print(" ");}System.out.print(P[i][j]+" ");}System.out.println();}System.out.println("----------------------------------------------------------------------"); }public void setInputString(String input) {inputString = input;}public boolean judge() {String inputChar = inputString.substring(0, 1); // 当前输入字符boolean flage = false;if (count1 >= 0) {for (int i=0; i<6; i++) {if (fenxi[count1].equals(Vt[i])) { // 判断分析栈栈顶的字符是否为终结符flage = true;break;}}}if (flage) {// 为终结符时if (fenxi[count1].equals(inputChar)) {if (fenxi[count1].equals("#")&&inputString.length()==1) { // 栈顶符号为结束标志时// System.out.println("最后一个");String fenxizhan = "";for (int i=0; i<=P.length; i++) { // 拿到分析栈里的全部内容(滤去null)if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" " + count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println("接受");flag = true;return true;} else {// 分析栈栈顶符号不为结束标志符号时String fenxizhan = "";for (int i=0; i<=P.length; i++) { // 拿到分析栈里的全部内容(滤去null)if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" "+count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println("\"" + inputChar + "\"" + "匹配");// 将栈顶符号出栈,栈顶指针减一fenxi[count1] = null;count1 -= 1;if (inputString.length() > 1) { // 当当前输入字符串的长度大于1时,将当前输入字符从输入字符串中除去inputString = inputString.substring(1, inputString.length());} else { // 当前输入串长度为1时inputChar = inputString;}// System.out.println(" "+count+" "+fenxizhan+"// "+inputString +" "+P[count3][count2]);// System.out.println(count + inputChar + "匹配");count++;judge();}}else { // 判断与与输入符号是否一样为结束标志System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}} else {// 非终结符时boolean fla = false;for (int i=0; i<6; i++) { // 查询当前输入符号位于终结符集的位置if (inputChar.equals(Vt[i])) {fla = true;count2 = i;break;}}if(!fla){System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}for (int i=0; i<5; i++) { // 查询栈顶的符号位于非终结符集的位置if (fenxi[count1].equals(Vn[i])) {count3 = i;break;}}if (P[count3][count2] != "error") { // 栈顶的非终结符与输入的终结符存在产生式时String p = P[count3][count2];String s1 = p.substring(2, p.length()); // 获取对应的产生式if (s1.equals("ε")) { // 产生式推出“ε”时String fenxizhan = "";for (int i=0; i<=P.length; i++) {if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" " + count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int k=0; k<farWay; k++) {System.out.print(" ");}System.out.println(fenxi[count1] + P[count3][count2]);// 将栈顶符号出栈,栈顶指针指向下一个元素fenxi[count1] = null;count1 -= 1;count++;judge();} else { // 产生式不推出“ε”时int k = s1.length();String fenxizhan = "";for (int i=0; i<=P.length; i++) {if (fenxi[i] == null) {break;} else {fenxizhan = fenxizhan + fenxi[i];}}// 输出当前分析栈情况,输入字符串,所用产生式或匹配System.out.print(" "+count);String countToString = Integer.toString(count);int farWay = 14 - countToString.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.print(fenxizhan);farWay = 20 - fenxizhan.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.print(inputString);farWay = 25 - inputString.length();for (int o=0; o<farWay; o++) {System.out.print(" ");}System.out.println(fenxi[count1] + P[count3][count2]);for (int i=1; i<=k; i++) { // 将产生式右部的各个符号入栈String s2 = s1.substring(s1.length() - 1, s1.length());s1 = s1.substring(0, s1.length() - 1);if (s2.equals("'")) {s2 = s1.substring(s1.length() - 1, s1.length())+ s2;i++;s1 = s1.substring(0, s1.length() - 1);}fenxi[count1] = s2;if (i < k)count1++;// System.out.println("count1=" + count1);}// System.out.println(" "+count+" "+fenxizhan+"// "+inputString +" "+P[count3][count2]);count++;// System.out.println(count);judge();}} else {System.out.println(" 分析到第" + count + "步时出错!");flag = false;return false;}}return flag;}public static void main(String args[]) {LL l = new LL();l.setP();String input = "";boolean flag = true;while (flag) {try {InputStreamReader isr = new InputStreamReader(System.in);BufferedReader br = new BufferedReader(isr);System.out.println();System.out.print("请输入字符串(输入exit退出):");input = br.readLine();} catch (Exception e) {e.printStackTrace();}if(input.equals("exit")){flag = false;}else{l.setInputString(input);l.setCount(1, 1, 0, 0);l.setFenxi();System.out.println();System.out.println("分析过程");System.out.println("----------------------------------------------------------------------");System.out.println(" 步骤| 分析栈| 剩余输入串| 所用产生式");System.out.println("----------------------------------------------------------------------");boolean b = l.judge();System.out.println("----------------------------------------------------------------------");if(b){System.out.println("您输入的字符串"+input+"是该文发的一个句子");}else{System.out.println("您输入的字符串"+input+"有词法错误!");}}}}}。

java词法分析器实验报告

java词法分析器实验报告

Java 词法分析器实验报告--07111101--奥特曼一.词法分析器功能概述:1.使用DFA实现词法分析器的设计;2.实现对Java源程序中注释和空格(空行)的过滤;3.利用两对半缓冲区从文件中逐一读取单词;4.词法分析结果属性字流存放在独立文件(c:\words.txt)中;5.统计源程序所有单词数以、错误单词数、单词所在的行数;6.具有报告词法错误和出错位置(源程序行号)的功能;二.源程序设计实现://程序大部分参照网络,自己做了小部分改动#include<iostream>#include<fstream>#include<cstdio>#include<cstdlib>#include<cstring>#include"const.h"using namespace std;char rbuf[RBUFSIZE]; //读文件缓冲区int rp; //读文件缓冲区指针char ch; //当前扫描到的字符int type; //单词的类型char sbuf[SBUFSIZE]; //单词字符串缓冲区int sp; //单词字符串缓冲区指针ifstream inFile; //输入文件ofstream outFile; //输出文件void clear_rbuf()//清空读文件缓冲区{int i;for(i=0;i<RBUFSIZE;i++)rbuf[i]='\0';rp=0;}void clear_sbuf()//清空单词字符缓冲区{int i;for(i=0;i<SBUFSIZE;i++)sbuf[i]='\0';sp=0;}void get_ch()//从读文件缓冲区得到下一个字符{ch=rbuf[rp];rp++;}void put_ch(char ch)//向字符缓冲区追加一个字符{sbuf[sp]=ch;sp++;}void get_type(char * msg)//得到单词类型{int i;for(i=0;i<TABLE_LENGTH;i++){if (!strcmp(msg, ATTR_MAP[i].keyword)){type=ATTR_MAP[i].type;return;}}return;}int digit(int base)//判断字符是否属于base进制并转换{char c=ch;int result;if (c>='0'&&c<='7')result = (int)(c - '0');else if(c>='8'&&c<='9'){if (base > 8)result=(int)(c-'0');elseresult = -1;}else if(c>='a'&&c<= 'f'){if (base>10)result=(int)(c-'a'+10);elseresult=-1;}else if (c>='A'&&c<='F'){if (base>10)result=(int)(c-'A'+10);elseresult=-1;}elseresult=-1;return result;}void scan_fraction()//扫描指数{while(digit(10)>=0){put_ch(ch);get_ch();}if(ch=='e'||ch=='E'){put_ch(ch);get_ch();if(ch=='+'||ch=='-'){put_ch(ch);get_ch();}while(digit(10)>=0){put_ch(ch);get_ch();}return;}return;}void scan_suffix() //扫描浮点数后缀{scan_fraction();if(ch=='f'||ch=='F'||ch=='d'||ch=='D'){put_ch(ch);get_ch();}type=T_FLOAT;return;}bool is_spectial(char &ch)//判断字符是否是特殊字符{if(ch=='!'||ch=='%'||ch=='&'||ch=='*'||ch=='?'||ch=='+'||ch=='-'||ch==':'||ch=='<'| |ch=='='||ch=='>'||ch=='^'||ch=='|'||ch=='~')return true;elsereturn false;}void scan_operator()//扫描运算符{while (is_spectial(ch)){put_ch(ch);get_ch();}get_type(sbuf);if(type==0)type=T_ERROR;return;}void scan_number(int radix)//扫描8、10、16进制数值{while(digit(radix)>=0){put_ch(ch);get_ch();}if(radix!=10&&ch=='.'){put_ch(ch);get_ch();type=T_ERROR;}else if(radix==10&&ch=='.'){put_ch('.');get_ch();if(digit(10)>=0)scan_suffix();}else if(radix==10&&(ch=='e'||ch=='E'||ch=='f'||ch=='F'||ch=='d'||ch=='D')) scan_suffix();else if(ch == 'l' || ch == 'L'){put_ch(ch);get_ch();type=T_INT;}else type=T_INT;return;}void skip_comment()//跳过注释内容{while(ch!='\0'){switch(ch){case'*':get_ch();if (ch=='/'){get_ch();return;}break;default:get_ch();break;}}}bool is_idchar(char &ch)//判断字符是否标识符首字符{return((ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='$'||ch=='_');}void scan_ident()//搜索关键字、标识符{bool id_or_key = true;bool tem=true;//是否仍是标识符或关键字while(ch!=C_TAB&&ch!=C_FF&&ch!=C_CR&&ch!=C_LF&&ch!='\0') {if(is_idchar(ch)){put_ch(ch);get_ch();if(is_idchar(ch))continue;elseget_type(sbuf);if(type!=0)return;else{type=T_IDENTIFIER;return;}}}}void scan_char()//转义字符搜索字符{int oct = 0;int hex = 0;if(ch=='\\'){get_ch();if(ch=='\\')put_ch('\\');get_ch();if(ch=='\'')put_ch('\'');get_ch();if(ch=='\"')put_ch('\"');get_ch();if(ch=='b')put_ch('\b');get_ch();if(ch=='t')put_ch('\t');get_ch();if(ch=='n')put_ch('\n');get_ch();if(ch=='f')put_ch('\f');get_ch();if(ch=='r')put_ch('\r');get_ch();if('0'<=ch&&ch<='7'){oct=digit(8);get_ch();if('0'<=ch&&ch<='7'){oct=oct*8+digit(8);get_ch();if('0'<=ch&&ch<='7'){oct=oct*8+digit(8);get_ch();}}put_ch((char)oct);}if(ch=='u'){get_ch();if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F')){hex=hex*16+digit(16);get_ch();if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F')){hex=hex*16+digit(16);get_ch();if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F')) {hex=hex*16+digit(16);get_ch();if(('0'<=ch&&ch<='9')||('a'<=ch&&ch<='f')||('A'<=ch&&ch<='F')){hex=hex*16+digit(16);get_ch();}}}}put_ch((char)hex);}}else{put_ch(ch);get_ch();}}void get_word()//获取下一个单词及属性{clear_sbuf();type=0;while (ch!='\0'){if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||ch=='$'||ch=='_')//关键字、标识符{scan_ident();return;}else if(ch=='\'')//字符{get_ch();if(ch=='\''){type=T_ERROR;strcpy(sbuf,"''");get_ch();}else{scan_char();if(ch=='\''){type=T_CHAR;get_ch();}else type=T_ERROR;}return;}else if(ch=='\"')//字符串{get_ch();{type=T_ERROR;strcpy(sbuf,"\"\"");get_ch();}else{do{scan_char();}while(ch!='\"'&&ch!=C_TAB&&ch!=C_FF&&ch!=C_CR&&ch!=C_LF);if(ch=='\"'){type=T_STRING;get_ch();}else type=T_ERROR;}return;}else if(ch=='.')//.开头数字{put_ch(ch);get_ch();if(digit(10)>=0)scan_suffix();else type=T_BOUND;return;}else if(ch=='0')//0开头数字{put_ch('0');get_ch();if(ch=='x'||ch=='X'){put_ch(ch);get_ch();if(digit(16)>=0&&ch!='0')scan_number(16);}else if(digit(8)>=0&&ch!='0')scan_number(8);{put_ch('.');get_ch();if(digit(10)>=0)scan_suffix();}else if(ch==' '){get_ch();type=T_INT;}else type=T_ERROR;return;}else if('1'<=ch&&ch<='9')//1-9开头数字{scan_number(10);return;}else if((ch=='(')||(ch==')')||(ch=='[')||(ch==']'))//9个界限符中的8个{put_ch(ch);get_ch();type = T_BOUND;return;}else if(ch==','){put_ch(ch);get_ch();type = T_COMMA;return;}else if((ch=='{')||(ch=='}')){put_ch(ch);get_ch();type = T_BRACKET;return;}else if(ch==';'){put_ch(ch);get_ch();type = T_SEMICOLON;return;}else if(ch=='/')//注释、'/'运算符、 '/='运算符 {get_ch();if(ch=='/'){while(ch!=C_CR&&ch!=C_LF&&ch!='\0') get_ch();break;}else if(ch=='*'){get_ch();skip_comment();}else if(ch=='='){strcpy(sbuf, "/=");type=T_ASSIGN;get_ch();}else{strcpy(sbuf, "/");type=T_MULDIV;}return;}else if(is_spectial(ch))//特殊字符{scan_operator();return;}else get_ch();//间隔符}}void readfile(char * fn_in)//将源文件读入缓冲区{rp = 0;inFile.open(fn_in);if (!inFile.is_open())return;while(inFile.get(rbuf[rp]))rp++;inFile.close();rp = 0;}void writefile()//向输出文件写字符{sp = 0;outFile << "(0x" << hex << type << ") ";outFile << "[";while(sbuf[sp]!='\0'){outFile << sbuf[sp];sp++;}outFile << "]";outFile << endl;sp = 0;}int main(int argc, char * argv[]){char fn_in[NAMESIZE];char fn_out[NAMESIZE];cout << "Input the name of Java source file: ";cin >> fn_in;readfile(fn_in);cout << "Input name of testing result file: ";cin >> fn_out;outFile.open(fn_out);get_ch();while(ch!='\0'){get_word();if(strlen(sbuf)!=0)writefile();}outFile.close();cout << "The analysis has been completed!" << endl;system("pause");return 0;}三.程序执行流程a.首先从Java文件中读取半个缓冲区的字符串读入预处理缓冲区中,将缓冲区中的注释、空行、空格全部处理,最后预处理缓冲区里面只剩下单词、一个空格、换行;b.将预处理缓冲区里面的的数据分两次读入两对半缓冲区ScanBuffer中,送入词法分析器wordScanner进行逐个单词分析,由wordScanner调用相应的转换函数进行单词属性的分析。

编译原理实验报告++词法分析器实验报告

编译原理实验报告++词法分析器实验报告

编译原理实验报告词法分析器制作与应用设计思想()程序主体结构部分:说明部分规则部分辅助程序部分()主体结构地说明在这里说明部分告诉我们使用地, (标识符,通常定义为字母开头地字母数字串)和(字符串常量,通常定义为双引号括起来地一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用来使用标准地头文件和前向说明( ,).这些代码应该再标记"{"和"}"之间;规则部分;可以包括任何你想用来分析地代码;我们这里包括了忽略所有注释中字符地功能,传送名称和字符串常量内容到主调函数和函数地功能.个人收集整理勿做商业用途()实现原理程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同地单词符号给出不同编码形式地编码,用以区分之.个人收集整理勿做商业用途语言地表示<常量定义>::<标识符><无符号整数>;<标识符>::<字母>{<字母><数字>};<加法运算符><乘法运算符>*<关系运算符><<>><字母>…<数字>…三:设计过程.关键字:,,,,,,,,,,,并为小写. 个人收集整理勿做商业用途."”;””;”*”;””;”“;”:”;”<“;”<“;”>“;”>“;”<>“;”“;”(“;”)”;”;”;””为运算符.个人收集整理勿做商业用途.其他标记如字符串,表示以字母开头地标识符..空格符跳过..各符号对应种别码关键字分别对应运算符分别对应,.字符串对应常量对应结束符四:举例说明目标:实现对常量地判别代码:[][][\[]({}[])({}{}[])*个人收集整理勿做商业用途{({}{}{})}{}[ \\] """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" {()("\");}个人收集整理勿做商业用途\"([])*\" {("\");}个人收集整理勿做商业用途?{}[.]{}?([][]?{})? {("\");}个人收集整理勿做商业用途""?{} {("\");} ","";""("")""{""}""[""]"">"".""!""""""""*"""""""""""""">""<"">""<""""""""^""""""""""""*"""""">> ""<<""""^""""" {("\");}个人收集整理勿做商业用途{} {("\");}{}({}) {("\");}个人收集整理勿做商业用途<>( * ){;(<){[]([]);}}(){;}五:六:数据测试七:心得体会其实匹配并不困难,主要是知识要求相对较高,只要把握住指针就好了.附源程序:<><><><>;* !*个人收集整理勿做商业用途;[] {" "};[];( []){*[] {"","","","","","",个人收集整理勿做商业用途"","","","","","",""};;;;[];* ** *(( > '') ( < '' )){(( > '') ( < '' )){[];[];};[] '\';( ; < ; )( ([]) )(){:{;;;}:{;;;}:{;;;}:{;;;}:{;;;}:{;;;} :{;;;} :{;;;} :{;;;} :{;;;} :{;;;}:{;;;}:{;;;}}( ){;}}* *(( > '') ( < '')){;(( > '' ) ( < '' )){*('');[];};;}* *(){'':{( '')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}'>':{( '>')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}'<':{( '<')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}'!':{( '!')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}'':{( '')[] ;[] '\';[];( ''){[] ;[] '\';;}( ''){[] ;[] '\';;}{;;};}'':{( '')[] ;[] '\';[];( ''){[] ;[] '\';;}( ''){[] ;[] '\';;{;;};}'*':{( '*')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}'':{( '')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}[] ; [] '\';; ;}'(':{[] ; [] '\';; ;}')':{[] ; [] '\';; ;}'[':{[] ; [] '\';; ;}']':{[] ; [] '\';; ;}'{':{[] ; [] '\';; ;}'}':{[] ; [] '\';; ;}':':{[] ;[] '\';;;}'"':{[] ;[] '\';;;}'':{( '')[] ;[] '\';[];( ''){[] ;[] '\';;}{;;};}',':{[] ;[] '\';;;}'':{[] ;[] '\';;;}'':{[] '';;;个人收集整理-ZQ}:{;;}};}(){;(" ");{();[] ;}( '');;{();( ){("()");}( ){("()");}{("()");}} ( );("");}11 / 11。

Java的编译原理

Java的编译原理概述java语⾔的"编译期"分为前端编译和后端编译两个阶段。

前端编译是指把*.java⽂件转变成*.class⽂件的过程; 后端编译(JIT, Just In Time Compiler)是指把字节码转变成机器码的过程。

在编译原理中, 将源代码编译成机器码, 主要经过下⾯⼏个步骤:Java中的前端编译java的前端编译(即javac编译)可分为解析与填充符号表、插⼊式注解处理器的注解处理、分析与字节码⽣成等三个过程。

解析与填充符号表解析步骤包括词法分析和语法分析两个阶段。

词法分析是将源代码的字符流转变为标记(Token)集合, 单个字符是程序编写过程的最⼩单位, ⽽标记则是编译过程的最⼩单位, 关键字、变量名、字⾯量、运算符都可以成为标记。

语法分析是根据Token序列构造抽象语法树的过程, 抽象语法树(AST)是⼀种⽤来描述程序代码语法结构的树形表⽰⽅式, 语法树的每⼀个节点都代表着程序代码中的⼀个语法结构, 如包、类型、修饰符、运算符、接⼝、返回值都可以是⼀个语法结构。

符号表是由⼀组符号地址和符号信息构成的表格。

在语法分析中, 符号表所登记的内容将⽤于语义检查和产⽣中间代码。

在⽬标代码⽣成阶段, 符号表是当对符号名进⾏地址分配时的依据。

插⼊式注解处理器插⼊式注解处理器可以看做是⼀组编译器的插件, 在这些插件⾥⾯, 可以读取、修改、添加抽象语法树中的任意元素。

如果这些插件在处理注解期间对语法数进⾏了修改, 编译器将回到解析与填充符号表的过程重新处理, 直到所有插⼊式注解处理器都没有再对语法数进⾏修改为⽌,每⼀次循环称为⼀个Round。

语义分析与字节码⽣成语法分析后, 编译器获得了程序代码的抽象语法树表⽰, 语法数能表⽰⼀个结构正确的源程序的抽象, 但⽆法保证源程序是符合逻辑的。

⽽语义分析的主要任务是对结构正确的源程序进⾏上下⽂有关性质的审查。

Javac的编译过程中, 语义分析过程分为标注检查、数据及控制流分析两个步骤。

编译原理第一次上机(词法分析器)

《词法分析器的构造》综合性实验大纲一、实验目的设计、编制、调试一个词法分析程序,对单词进行识别和编码,加深对词法分析原理的理解。

二、设计内容设计并实现一个词法分析器,实现对指定位置的类C语言源程序文本文件的读取,并能够对该源程序中的所有单词进行分类,指出其所属类型,实现简单的词法分析操作。

例如下面为一段C语言源程序:main(){int a,b;a = 10;b = a + 20;}要求输出如下(可以自行分类,分类原则请在报告中说明)(1,’main’)(5,’(’)(5,’)’)(5,’{ ’)(1,’int’)(2,’a’)(5,’,’)(2,’b’)(5,’;’)(2,’a’)(4,’=’)(3,’10’)(5,’;’)(2,’b’)(4,’=’)(2,’a’)(4,’+’)(3,’20’)(5,’;’)(5,’}’)三、实验要求1、允许用户自己输入源程序并保存为文件2、系统能够输出经过预处理后的源程序(去掉注释、换行、空格等)3、能够将该源程序中所有的单词根据其所属类型(整数、保留字、运算符、标识符等。

定义的类C语言中的标识符只能以字母或下划线开头)进行归类显示,例如:识别保留字:if、int、for、while、do、return、break、continue等,其他的都识别为标识符;常数为无符号整形数;运算符包括:+、-、*、/、=、>、<、>=、<=、!=等;分隔符包括:,、;、{、}、(、)等。

4、实现文件的读取操作,而不是将文本以字符串形式预存于程序中。

文本内容为待分析的类C语言程序。

四、实验报告实验报告的内容:实验名称、实验目的、实验任务、实验内容、实验过程描述(包括实验结果分析、实验过程遇到的问题及体会)。

实验报告的要求:实验报告以文本或电子版形式递交,实验报告书写要求如下:1. 问题描述:包括实验名称、目的、内容(包括所识别的单词文法),以简洁明了的叙述说明本次上机实验的任务和目标,程序的输入和输出要求以及程序的功能。

编译原理实验报告

编译原理实验报告一、实验目的编译原理是计算机科学中的重要课程,旨在让学生了解编译器的基本工作原理以及相关技术。

本次实验旨在通过设计和实现一个简单的编译器,来进一步加深对编译原理的理解,并掌握实际应用的能力。

二、实验环境本次实验使用了Java编程语言及相关工具。

在开始实验前,我们需要安装Java JDK并配置好运行环境。

三、实验内容及步骤1. 词法分析词法分析是编译器的第一步,它将源代码分割成一系列词法单元。

我们首先实现一个词法分析器,它能够将输入的源代码按照语法规则进行切割,并识别出关键字、标识符、数字、运算符等。

2. 语法分析语法分析是编译器的第二步,它将词法分析得到的词法单元序列转化为语法树。

我们使用自顶向下的LL(1)语法分析算法,根据文法规则递归地构建语法树。

3. 语义分析语义分析是编译器的第三步,它对语法树进行检查和转换。

我们主要进行类型检查、语法错误检查等。

如果源代码存在语义错误,编译器应该能够提供相应的错误提示。

4. 代码生成代码生成是编译器的最后一步,它将经过词法分析、语法分析和语义分析的源代码翻译为目标代码。

在本次实验中,我们将目标代码生成为Java字节码。

5. 测试与优化完成以上步骤后,我们需要对编译器进行测试,并进行优化。

通过多个测试用例的执行,我们可以验证编译器的正确性和性能。

四、实验心得通过完成这个编译器的实验,我收获了很多。

首先,我对编译原理的知识有了更深入的理解。

在实验过程中,我深入学习了词法分析、语法分析、语义分析和代码生成等关键技术,对编译器的工作原理有了更系统的了解。

其次,我提高了编程能力。

实现一个完整的编译器需要处理复杂的数据结构和算法,这对我的编程能力是一个很好的挑战。

通过实验,我学会了合理地组织代码,优化算法,并注意到细节对程序性能的影响。

最后,我锻炼了解决问题的能力。

在实验过程中,我遇到了很多困难和挑战,但我不断地调试和改进代码,最终成功地实现了编译器。

编译原理的词法分析与语法分析

编译原理的词法分析与语法分析编译原理是计算机科学中的一门重要课程,它研究如何将源代码转换为可执行的机器代码。

在编译过程中,词法分析和语法分析是其中两个基本的阶段。

本文将分别介绍词法分析和语法分析的基本概念、原理以及实现方法。

1. 词法分析词法分析是编译过程中的第一个阶段,主要任务是将输入的源代码分解成一个个的词法单元。

词法单元是指具有独立意义的最小语法单位,比如变量名、关键字、操作符等。

词法分析器通常使用有限自动机(finite automaton)来实现。

在词法分析的过程中,需要定义词法规则,即描述每个词法单元的模式。

常见的词法规则有正则表达式和有限自动机。

词法分析器会根据这些规则匹配输入的字符序列,并生成相应的词法单元。

2. 语法分析语法分析是编译过程中的第二个阶段,它的任务是将词法分析器生成的词法单元序列转换为语法树(syntax tree)或抽象语法树(abstract syntax tree)。

语法树是源代码的一种抽象表示方式,它反映了源代码中语法结构和运算优先级的关系。

语法分析器通常使用上下文无关文法(context-free grammar)来描述源代码的语法结构。

常见的语法分析算法有递归下降分析法、LR分析法和LL分析法等。

递归下降分析法是一种自顶向下的分析方法,它从源代码的起始符号开始,递归地展开产生式,直到匹配到输入的词法单元。

递归下降分析法的实现比较直观,但对于左递归的文法处理不方便。

LR分析法是一种自底向上的分析方法,它使用一个自动机来分析输入的词法单元,并根据文法规则进行规约操作,最终生成语法树。

常见的LR分析法有LR(0)、SLR、LR(1)和LALR等。

LL分析法是一种自顶向下的分析方法,它从源代码的起始符号开始,预测下一个要匹配的词法单元,并进行相应的推导规则。

LL分析法常用于编程语言中,如Java和Python。

3. 词法分析和语法分析的关系词法分析是语法分析的一个子阶段,它为语法分析器提供了一个符号序列,并根据语法规则进行分析和匹配。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一词法分析器的设计一、实验目的1.理解词法分析器的任务和输出形式2.理解扫描器的工作原理3.掌握状态转换图的绘制以及单词的识别技术4.掌握词法分析器的设计过程,能够使用某种高级语言实现一个词法分析器二、实验环境Myeclipse三、实验要求给出一个简单的词法语言规则描述,其中:1开头的种别码为关键词,2开头的为算符,3开头的为界符,4开头的为标识符,5开头的为常数,标识符为字母开头,以字母和数字组成的任意符号串,常数为整数,即以数字组成的符号串。

四、实验难点1.对整数的二进制转换,以及对指针的操作2.标识符的设置五、实验代码1.ciFa.Javapackage com.yaoer.test1;import javax.swing.*;import javax.swing.border.TitledBorder;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;@SuppressWarnings("serial")public class ciFa extends JFrame{private JButton jbtShow = new JButton("进行词法分析");//按钮private JTextArea jta = new JTextArea();//输入文本框private JTextArea jtaOut = new JTextArea();//输出文本框private JPanel jpl=new JPanel();private String intput ="";private String output ="";private compiler comp = new compiler();* @param args*/public static void main(String[] args){ciFa frame = new ciFa();frame.setTitle("词法分析器");//frame.setLocationRelativeTo(frame);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(500, 400);frame.setVisible(true);}public ciFa(){jta.setWrapStyleWord(true);jta.setLineWrap(true);jtaOut.setWrapStyleWord(true);jtaOut.setLineWrap(true);jtaOut.setEditable(false);JScrollPane scrollPane = new JScrollPane(jta);JScrollPane scrollPane2 = new JScrollPane(jtaOut);scrollPane.setPreferredSize(new Dimension(300,300));scrollPane2.setPreferredSize(new Dimension(300,300));jtaOut.setBorder(new TitledBorder("词法分析结果"));jta.setBorder(new TitledBorder("请在这输入"));jpl.setLayout(new GridLayout(2,2));jpl.add(jta);jpl.add(jtaOut);add(jbtShow,BorderLayout.SOUTH);add(jpl);jbtShow.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){intput = jta.getText();output=puterComp(intput);jtaOut.append(output);}});}piler.Javapackage com.yaoer.test1;public class compiler {public String computerComp(String str){String output="";int index=0;int k = 0;while(index<str.length()){if(isJieFu(str.charAt(index))!=-1){ //判断界符output+=("( 30"+isJieFu(str.charAt(index))+" "+str.charAt(index)+" 界符)");index++;}else if(isMath(str.charAt(index))){ //判断常数int index1=index;output+=("( ");String sub;String result;while(isMath(str.charAt(index))){output+=(str.charAt(index));index++;if(index>=str.length()){if(str.charAt(index1)=='0'){if(index1+1>=str.length()){sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}else{if(isMath(str.charAt(index1+1))){output+=(" 非法字符)"); }else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}}else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}return output;}}if(isLetter(str.charAt(index))){if(str.charAt(index)==' '||str.charAt(index)=='\n'){//空格或者回车处理index++;}while((!isMath(str.charAt(index)))||(isLetter(str.charAt(index)))){output+=(str.charAt(index));index++;if(index>=str.length()) {output+=(" 非标识符)");return output;}}output+=(" 非法字符)");}else{if(str.charAt(index1)=='0'){if(isMath(str.charAt(index1+1))){output+=(" 非法字符)"); }else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}}else if(isLetter(str.charAt(index))){ //标识符判断int i=index;String sub;while(isLetter(str.charAt(index))||isMath(str.charAt(index))){index++;if(index>=str.length()){//System.out.println(index);sub =str.substring(i, index);if(isKeyword(sub)!=0){if(isKeyword(sub)>=10){output+=("( "+" 1"+isKeyword(sub)+" "+sub+" 关键字)");}else{output+=("( "+" 10"+isKeyword(sub)+" "+sub+" 关键字)");}}else{output+=("( "+sub+" 标识符)");}return output;}}sub = str.substring(i, index);//判断是不是关键字if(isKeyword(sub)!=0){if(isKeyword(sub)>=10){output+=("( "+" 1"+isKeyword(sub)+" "+sub+" 关键字)");}else{output+=("( "+" 10"+isKeyword(sub)+" "+sub+" 关键字)");}}else{output+=("("+sub+" 标识符)");}}else if(isCompu(str.charAt(index))!=0){if(index+1>=str.length()){if(str.charAt(index)=='&'||str.charAt(index)=='|'){output+=("("+str.charAt(index)+" 非法字符)");index++;}else{if(isCompu(str.charAt(index))<=8){output+=("("+" 20"+isCompu(str.charAt(index))+" "+str.charAt(index)+" 运算符)");}else if(str.charAt(index)=='!'){output+=("( 218 "+str.charAt(index)+" 运算符)");}index++;}}else{if(isCompu(str.charAt(index+1))==0){if(str.charAt(index)=='&'||str.charAt(index)=='|'){output+=("("+str.charAt(index)+" 非法字符)");index++;}else{if(isCompu(str.charAt(index))<=8){output+=("("+"20"+isCompu(str.charAt(index))+" "+str.charAt(index)+" 运算符)");}else if(str.charAt(index)=='!'){output+=("("+" 218"+str.charAt(index)+" 运算符)");}index++;}}else{if(index+2>=str.length()){if( isCompu(str.charAt(index+1))!=0){if(str.charAt(index)=='='){if(str.charAt(index+1)=='='){output+=("("+" 210 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='<' ){switch (str.charAt(index+1)) {case '=':output+=("("+" 209 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '<':output+=("( 215 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '>':output+=("( 211 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;default:output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;break;}}else if(str.charAt(index)=='>' ){if(str.charAt(index+1)=='='){output+=("( 207 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else if(str.charAt(index+1)=='>'){output+=("( 214 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='&'){if(str.charAt(index+1)=='&'){output+=("( 216 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='|'){if(str.charAt(index+1)=='|'){output+=("( 217 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='+'){if(str.charAt(index+1)=='+'){output+=("( 212 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='-'){if(str.charAt(index+1)=='-'){output+=("( 213 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}return output;}else{if( isCompu(str.charAt(index+1))!=0){if(str.charAt(index)=='='){if(str.charAt(index+1)=='='){output+=("("+" 210 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='<' ){switch (str.charAt(index+1)) {case '=':output+=("("+" 209 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '<':output+=("("+" 215 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '>':output+=("( 211 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;default:output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;break;}}else if(str.charAt(index)=='>' ){if(str.charAt(index+1)=='='){output+=("( 207 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else if(str.charAt(index+1)=='>'){output+=("( 214 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='&'){if(str.charAt(index+1)=='&'){output+=("( 216 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='|'){if(str.charAt(index+1)=='|'){output+=("( 217 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='+'){if(str.charAt(index+1)=='+'){output+=("( 212"+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='-'){if(str.charAt(index+1)=='-'){output+=("( 213 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}}}}}else if(str.charAt(index)==' '||str.charAt(index)=='\n'){//空格或者回车处理index++;}else {//其他字符output+=("("+str.charAt(index)+" 非法字符)");index++;}k++;if(k%10==0){output+=("\n");}}return output;}/*** 1.判断是不是关键字* @param str* @return*/public int isKeyword(String str){int result = 0;String[]arr={"void","main","int","char","if","else","for","while","return","cout","ci n"} ;for(int i=0;i<arr.length;i++){if(str.equals(arr[i])){result = i+1;break;}else {result = 0;}}return result;}/*** 2.判断是不是运算符* @param charr* @return*/public int isCompu(char charr) {char arr[]={'+','-','*','/','=','>','&','<','!','|'};for(int i=0;i<arr.length;i++) {if (charr==arr[i]){return i+1;}}return 0;}/*** 3.判断是不是界符* @param charr* @return*/public int isJieFu(char charr){char arr[]={'(',')','[',']','{','}',',',';'};for(int i=0;i<arr.length;i++){if (charr==arr[i]){return i+1;}}return -1;}/*** 4.判断是不是标识符* @param charr* @return*/public boolean isLetter(char charr){if(((charr>='a'&&charr<='z')||(charr>='A'&&charr<='Z')) ||charr=='_'){ return true;}else{return false;}}/*** 5.判断是不是数字* @param charr* @return*/public boolean isMath(char charr){if((charr>='0')&&(charr<='9')){return true;}else{return false;}}/*** 将十进制转换为二进制* @param num* @return*/public String Zhuan(String num){int number = Integer.parseInt(num);int sum;String result = "";for (int i = number; i >= 1; i /= 2) {if (i % 2 == 0) {sum = 0;} else {sum = 1;}result = sum + result;}return result;}}六、实验中遇到的问题及感想在编写词法分析器的程序中,几个子函数的功能还是比较容易实现的,但是要把它们的功能连在一起,实现对程序源代码的词法分析就困难了,例如在分析运算符的时候,有的运算符是由2个符号组成的,有的是1个,在读入一个字符的时候还要进行超前搜索,看看第二个字符是否可以和第一个字符组成一个运算符。

相关文档
最新文档