精华内容
下载资源
问答
  • 编译过程概述: 编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。从概念上来讲,一个编译程序的整个工作过程是划分成阶段进行的,每个阶段将源程序的一种表示形式转换成另一种表示形式,各个...

    编译过程概述:
    编译程序完成从源程序到目标程序的翻译工作,是一个复杂的整体的过程。从概念上来讲,一个编译程序的整个工作过程是划分成阶段进行的,每个阶段将源程序的一种表示形式转换成另一种表示形式,各个阶段进行的操作在逻辑上是紧密连接在一起的,典型的划分方法主要分为6个阶段、如下:
    源程序 -> 词法分析 -> 语法分析 -> 语义分析 -> 中间代码生成 -> 代码优化 -> 目标代码生成 -> 目标程序


    下面分别简单介绍一下6个阶段的任务

    1、词法分析:
    词法分析是编译过程的第一个阶段,这个阶段的任务是从左到右一个字符一个字符的读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(一些场合下也称单词符号或符号)。这里所谓的单词是指逻辑上紧密相连的一组字符,这些字符具有集体含义。
    在这个阶段,会将程序变成由标识符、保留字、算符、界符等组成的单词序列。并且自动把空格过滤掉。其中标识符会以id1、id2、id3……这样的内部形式存在。

    2、语法分析:
    语法分析是编译过程的第二个阶段。语法分析的任务是在词法分析的基础上将单词序列分解成各类语法短语,如“程序”、“语句”、“表达式”等。这种语法短语也称为语法单位,可以表示成语法树
    这里写图片描述
    语法分析所依据的是语言的语法规则,即描述程序结构的规则。通过语法分析确定整个输入串是否构成一个语法上正确的程序。程序的结构通常是由递归规则表示的。

    词法分析和语法分析本质上都是对源程序的结构进行分析。但词法分析的任务仅对源程序进行线性扫描即可完成,比如识别标识符,因为标识符的结构是字母打头的字母和数字串,这只要顺序扫描输入流,遇到既不是字母又不是数字的字符时,将前面所发现的所有字母和数字组合在一起构成标识符单词即可。但这种线性扫描不能用于递归定义的语法成分,比如不能用此办法去匹配表达式中的括号。

    3、语义分析:
    语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。例如,语义分析的一个工作是进行类型审查,审查每个算符是否具有语言规范允许的运算对象,当不符合语言规范时,编译程序应报告错误。

    4、中间代码生成:
    在进行了上述的语法分析和语义分析阶段的工作后,有的编译程序将源程序变成一种内部表示形式,这种内部表示形式叫做中间语言或中间代码。所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统可以设计为多种多样的形式,重要的设计原则为两点:
    (1)容易生成
    (2)容易将它翻译成目标代码
    很多编译程序采用了一种近似“三地址指令”的“四元式”中间代码,这种四元式形式为:
    (运算符,运算对象1,运算对象2,结果)

    5、代码优化:
    这一阶段的任务是对前一阶段产生的中间代码进行变换或进行改造,目的是使生成的目标代码更为高效,即省时间和省空间。一系列的优化工作诸如公共子表达式的删除、强度削弱、循环优化等优化工作将会在后面的博客里详细介绍。

    6、目标代码生成:
    这一阶段的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。这是编译的最后阶段,它的工作与硬件系统结构和指令含义有关,这个阶段的工作很复杂,涉及硬件系统功能部件的运用、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后缓寄存器的调度等。


    上述就是编译程序的几个工作阶段。但事实上并非所有的编译程序都分成这样几个阶段,有些编译程序并不需要生成中间代码,有些编译程序不进行优化,即优化阶段可省去,有些最简单的编译程序在语法分析的同时产生目标指令代码,如 PL/0 语言编译程序。不过多数实用的编译程序都包含上述几个阶段的工作。

    展开全文
  • 编译原理:语法分析器

    万次阅读 多人点赞 2019-04-29 17:01:40
    描述总体设计思路和主要的流程图。 语法分析的方法是LL(1)文法。 设计思路: 1.构造单个文法符号X的first集: 如果X为终结符,First(X)=X; 如果X->ε是产生式,把ε加入First(X); 如果X是非终结符...

    语法分析程序



    一、作业目的和要求

    通过设计、编制、调试一个典型的语法分析程序(任选有代表性的语法分析方法,如LL(1)、递归下降分析法、LR、算符优先分析法)等,作为编制语法分析程序的依据,对词法分析器所提供的单词序列进行语法检测和结构分析,实现并进一步掌握常用的语法分析方法。


    二、作业内容

    选择对各种常见高级程序设计语言都较为通用的语法结构作为分析对象(例如表达式、if、while、for等等),给出其文法规则描述(注意,文法规则的描述要符合所选分析方法的要求,比如用LL(1)分析法,文法必须是LL(1)文法),设计并实现一个完整的语法分析程序。

    • 输入:源程序以文件的形式输入。
    • 输出:对于输入的源程序,如果输入源程序是给定文法定义的合法程序,则输出”success”,如果不是,即输入源程序有错误,则输出“Error”,并且尽可能指出出错位置和原因。

    三、作业要求

    1、说明语法分析的源语言是什么?
    能分析的语法成分有哪些(比如if、while、表达式、switch等等)。
    给出每个语法规则的文法描述。(可以自定义语法成分,设计合理的语法规则。)

    运用的Java语言写成的语法分析程序,
    语法成分包括:if选择结构,while循环结构,for循环结构。

    2、说明选择的语法分析方法是哪种?描述总体设计思路和主要的流程图。

    语法分析的方法是LL(1)文法。

    • 设计思路:

    • 1.构造单个文法符号X的first集:
      如果X为终结符,First(X)=X;
      如果X->ε是产生式,把ε加入First(X);
      如果X是非终结符,如X->YZW。从左往右扫描产生式右部,把First(Y)加入First(X); 如果First(Y)不包含ε,表示Y不可为空,便不再往后处理;如果First(Y)包含ε,表示Y可为空,则处理Z,依次类推。
      构造文法符号串的first集,如:X->YZW;求YZW的first集
      从左往右扫描该式,加入其非空first集:把First(Y)加入First(YZW)
      若包含空串,处理下一个符号:如果First(Y)包含空串,便处理Z;不包含就退出;处理到尾部,即所有符号的first集都包含空串 把空串加入First(YZW)。

    • 2.在计算First(X)集之后的基础上:
      (1)$属于FOLLOW(S),S是开始符;
      (2)查找输入的所有产生式,确定X后紧跟的终结符;
      (3)如果存在A->αBβ,(α、β是任意文法符号串,A、B为非终结符),把first(β)的非空符号加入follow(B);
      (4)如果存在A->αB或A->αBβ 但first(β)包含空,把follow(A)加入follow(B)。

    • 3.构造预测分析表:
      对于每个产生式A->α,first(α)中的终结符a,把A->α加入M[A,a]。
      如果空串在first(α)中,说明可为空,找它的follow集,对于follow(A)中的终结符b,把A->α加入M[A,b];
      如果空串在first(α)中,且 “$”也在follow(A)中,说明A后可以接终结符,故把A->α加入M[A,$]中。

    • 4.执行分析:
      输入一个串,文法G的预测分析表,输出推导过程:
      $ 和 开始符S入栈,栈顶符号X,index指向分析串的待分析符号a。
      栈非空执行以下循环:
      如果X==a,表示匹配,符号栈弹出一个,index++指向下一个符号;
      否则,如果X是终结符,出错;
      否则,如果查表为error,出错;
      否则,查表正确,弹出栈顶符号,把其右部各个符号进栈,令X为栈顶符号。

    • 流程图:
      在这里插入图片描述
      在这里插入图片描述

    3、编程实现,程序中编写的各种函数,需要给出注释,说明函数的作用。
    通过实现接口中的方法来完成语法分析的功能。

    package Try;
    
    interface MyAnalyseFun {
        void Init();//初始化
        void getVnVt();//获取非终结符和终结符的集合
        void getFirst(Character c);//first集
        void getFirst(String s);//任意字符的first集
        void getFollow(char c);//follow集
        void createTable();//构造表
        void analyzeLL();//LL(1)分析过程
        String find(char X, char a);//查找
        void insert(char X, char a,String s);//插入
        void displayLL();//输出分析过程
        void ouput();//其他输出信息
    }
    

        package Try;
        
        import java.io.*;
        import java.util.*;
        
        public class MyAnalyse implements MyAnalyseFun{
            /**
             * 几个比较重要的参数
             * @param MyfirstSet 终结符的first集合
             * @param MyfirstSetX 任意符号的first集合
             * @param start 文法的开始符
             * @param MyfollowSet follow集
             * @param VnSet 终结符的集合
             * @param VtSet 终结符的集合
             * @param inputStrings 文法拓展的输入
             * @param outputSet 输出的集合
             * @param table 分析表
             * @param MyAnaStatck 分析栈
             * @param strInput 需要使用预测分析器的输入串
             * @param MyAction 分析动作
             * @param Index 分析的索引值
             */
            //从文件中读入时后台无法识别空串ε,因此用符号&代替空串ε
    
        //first集是终结符的first集
        protected HashMap<Character, HashSet<Character>> MyfirstSet = new HashMap<>();
        //firstX集是指任意符号串的first集
        protected HashMap<String, HashSet<Character>> MyfirstSetX = new HashMap<>();
        //文法的开始符
        protected Character start = 'S';
        //follow集
        protected HashMap<Character, HashSet<Character>> MyfollowSet = new HashMap<>();
    
        //存储非终结符的结合
        protected HashSet<Character> VnSet = new HashSet<>();
        //存储终结符的结合
        protected HashSet<Character> VtSet = new HashSet<>();
        protected HashMap<Character, ArrayList<String>> outputSet = new HashMap<>();
        //输入文法
        //S->a|^|(T)
        //T->SU
        //U->,SU|&
    //    protected String [] inputStrings = {   "S->a",
    //                                        "S->^",
    //                                        "S->(T)",
    //                                        "T->SU",
    //                                        "U->,SU",
    //                                        //"U->ε",
    //                                        "U->&"   };
        //定义分析表
        protected String [][] table;
        //分析栈
        protected Stack<Character> MyAnaStatck = new Stack<>();
        //定义要分析的输入串
        protected String strInput = "(a,a)$";
        //对动作的初始化
        protected String MyAction = "";
        int Index = 0;
    
        //从文件中读入
        protected String[] inputStrings = getSource();
    
        protected MyAnalyse() {
        }
    
        public static void main(String[] args){
            MyAnalyse test = new MyAnalyse();
    
            test.getVnVt();
            test.Init();
            test.createTable();
            test.analyzeLL();
            test.ouput();
            
        }
    
        //从文件中读入文法的方法
        public  static  String[] getSource(){
            StringBuffer temp = new StringBuffer();
            FileInputStream fis= null;
            try {
                fis = new FileInputStream("E:\\readin.txt");
                byte[] buff=new byte[1024];
                int len=0;
                while((len=fis.read(buff))!=-1){
                    temp.append(new String(buff,0,len));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return temp.toString().split("\n");
        }
    
        //初始化
        @Override
        public void Init() {
            for (String s1 : inputStrings) {
                //"S->a",
                //"S->^",
                //"S->(T)",
                //"T->SU",
                //"U->,SU",
                //"U->&"
                String[] str = s1.split("->");//通过符号“->”分隔每行的文法
                char c = str[0].charAt(0);//取得左边的非终结符
                ArrayList<String> list = outputSet.containsKey(c) ? outputSet.get(c) : new ArrayList<>();
                list.add(str[1]);//添加文法右边的内容到集合中
                outputSet.put(c, list);
            }
            //求非终结符的first集
            for (Character c1 : VnSet)
                getFirst(c1);
    
            for (Character c2 : VnSet) {
                ArrayList<String> l = outputSet.get(c2);
                for (String s2 : l)
                    getFirst(s2);
            }
            //求出follow集
            getFollow(start);
            for (Character c3 : VnSet) {
                getFollow(c3);
            }
        }
    
        @Override
        public void getVnVt() {//取出终结符和非终结符的集合
            for (String s3 : inputStrings) {
                String[] str = s3.split("->");
                VnSet.add(str[0].charAt(0));
            }
            for (String s4 : inputStrings) {
                String[] str = s4.split("->");
                String right = str[1];
                for (int i = 0; i < right.length(); i++)
                    if (!VnSet.contains(right.charAt(i)))
                        VtSet.add(right.charAt(i));
            }
        }
    
        @Override
        public void getFirst(Character c) {
            ArrayList<String> list = outputSet.get(c);
            HashSet<Character> set = MyfirstSet.containsKey(c) ? MyfirstSet.get(c) : new HashSet<Character>();
            // c为终结符 直接添加
            if (VtSet.contains(c)) {
                set.add(c);
                MyfirstSet.put(c, set);
                return;
            }
            // c为非终结符 处理其每条产生式
            for (String s5 : list) {
                // c 推出空串 直接添加
                if (s5 == Character.toString('&')) {
                    set.add('&');
                }
                // X -> Y1Y2Y3… 情况
                else {
                    // 从左往右扫描生成式右部
                    int i = 0;
                    while (i < s5.length()) {
                        char tn = s5.charAt(i);
                        //先处理防止未初始化
                        getFirst(tn);
                        HashSet<Character> tvSet = MyfirstSet.get(tn);
                        // 将其first集加入左部
                        for (Character tmp : tvSet)
                            set.add(tmp);
                        // 若包含空串 处理下一个符号
                        if (tvSet.contains('&'))
                            i++;
                            // 否则退出 处理下一个产生式
                        else
                            break;
                    }
                }
            }
            MyfirstSet.put(c, set);
        }
    
        @Override
        public void getFirst(String s) {
            HashSet<Character> set = (MyfirstSetX.containsKey(s))? MyfirstSetX.get(s) : new HashSet<Character>();
            // 从左往右扫描该式
            int i = 0;
            while (i < s.length()) {
                char tn = s.charAt(i);
                HashSet<Character> tvSet = MyfirstSet.get(tn);
                // 将其非空 first集加入左部
                for (Character tmp : tvSet)
                    if(tmp != '&')
                        set.add(tmp);
                // 若包含空串 处理下一个符号
                if (tvSet.contains('&'))
                    i++;
                    // 否则结束
                else
                    break;
                // 到了尾部 即所有符号的first集都包含空串 把空串加入
                if (i == s.length()) {
                    set.add('&');
                }
            }
            MyfirstSetX.put(s, set);
        }
    
        @Override
        public void getFollow(char ch) {
            ArrayList<String> list = outputSet.get(ch);
            HashSet<Character> setA = MyfollowSet.containsKey(ch) ? MyfollowSet.get(ch) : new HashSet<Character>();
            //如果是开始符 添加 $
            if (ch == start) {
                setA.add('$');
            }
            //查找输入的所有产生式,确定c的后跟 终结符
            for (Character cha : VnSet) {
                ArrayList<String> l = outputSet.get(cha);
                for (String s : l)
                    for (int i = 0; i < s.length(); i++)
                        if (s.charAt(i) == ch && i + 1 < s.length() && VtSet.contains(s.charAt(i + 1)))
                            setA.add(s.charAt(i + 1));
            }
            MyfollowSet.put(ch, setA);
            //处理c的每一条产生式
            for (String s : list) {
                int i = s.length() - 1;
                while (i >= 0 ) {
                    char tn = s.charAt(i);
                    //只处理非终结符
                    if(VnSet.contains(tn)){
                        // 都按 A->αB&  形式处理
                        //若&不存在   followA 加入 followB
                        //若&存在,把&的非空first集  加入followB
                        //若&存在  且 first(&)包含空串   followA 加入 followB
    
                        //若&存在
                        if (s.length() - i - 1 > 0) {
                            String right = s.substring(i + 1);
                            //非空first集 加入 followB
                            HashSet<Character> setF = null;
                            if( right.length() == 1 && MyfirstSet.containsKey(right.charAt(0))) {
                                setF = MyfirstSet.get(right.charAt(0));
                            }
                            else{
                                if(!MyfirstSetX.containsKey(right)){
                                    HashSet<Character> set = new HashSet<Character>();
                                    MyfirstSetX.put(right, set);
                                }
                                setF = MyfirstSetX.get(right);
                            }
                            HashSet<Character> setX = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                            for (Character cha : setF) {
                                if (cha != '&') {
                                    setX.add(cha);
                                }
                            }
                            MyfollowSet.put(tn, setX);
    
                            // 若first(&)包含&   followA 加入 followB
                            if(setF.contains('&')){
                                if(tn != ch){
                                    HashSet<Character> setB = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                                    for (Character cha : setA) {
                                        setB.add(cha);
                                    }
                                    MyfollowSet.put(tn, setB);
                                }
                            }
                        }
                        //若&不存在   followA 加入 followB
                        else{
                            // A和B相同不添加
                            if(tn != ch){
                                HashSet<Character> setB = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                                for (Character cha : setA)
                                    setB.add(cha);
                                MyfollowSet.put(tn, setB);
                            }
                        }
                        i--;
                    }
                    //如果是终结符往前扫描  如 A->aaaBCDaaaa  此时&为 CDaaaa
                    else i--;
                }
            }
        }
    
        @Override
        public void createTable() {//构造预测分析表的格式
            //终结符数组
            Object[] VtArray = VtSet.toArray();
            //非终结符数组
            Object[] VnArray = VnSet.toArray();
            // 预测分析表初始化
            table = new String[VnArray.length + 1][VtArray.length + 1];
            table[0][0] = "Vn/Vt";
            //初始化首行首列
            for (int i = 0; i < VtArray.length; i++)
                table[0][i + 1] = (VtArray[i].toString().charAt(0) == '&') ? "$" : VtArray[i].toString();
            for (int i = 0; i < VnArray.length; i++)
                table[i + 1][0] = VnArray[i] + "";
            //全部置error
            for (int i = 0; i < VnArray.length; i++)
                for (int j = 0; j < VtArray.length; j++)
                    table[i + 1][j + 1] = "error";
    
            //插入生成式
            for (char A : VnSet) {
                ArrayList<String> l = outputSet.get(A);
                for(String s : l){
                    HashSet<Character> set = MyfirstSetX.get(s);
                    for (char a : set)
                        insert(A, a, s);
                    if(set.contains('&'))  {//如果包含&
                        HashSet<Character> setFollow = MyfollowSet.get(A);
                        if(setFollow.contains('$'))//判断follow集中是否包含$
                            insert(A, '$', s);
                        for (char b : setFollow)
                            insert(A, b, s);
                    }
                }
            }
        }
    
        @Override
        public void analyzeLL() {
            System.out.println("-------------------1.LL分析过程-------------------");
            System.out.println("|               分析栈        输入串     动作|  ");
            MyAnaStatck.push('$');
            MyAnaStatck.push('S');
            displayLL();//调用分析过程方法
            char X = MyAnaStatck.peek();
            while (X != '$') {
                char a = strInput.charAt(Index);
                if (X == a) {
                    MyAction = "match " + MyAnaStatck.peek();
                    MyAnaStatck.pop();
                    Index++;
                } else if (VtSet.contains(X))
                    return;
                else if (find(X, a).equals("error"))
                    return;
                else if (find(X, a).equals("&")) {
                    MyAnaStatck.pop();
                    MyAction = X + "->&";
                } else {
                    String str = find(X, a);
                    if (str != "") {
                        MyAction = X + "->" + str;
                        MyAnaStatck.pop();
                        int len = str.length();
                        for (int i = len - 1; i >= 0; i--)
                            MyAnaStatck.push(str.charAt(i));
                    } else {
                        System.out.println("error at '" + strInput.charAt(Index) + " in " + Index);
                        return;
                    }
                }
                X = MyAnaStatck.peek();
                displayLL();
            }
            System.out.println("LL(1)文法分析成功!");
            System.out.println("-------------------LL分析过程-------------------");
        }
    
        @Override
        public String find(char X, char a) {
            for (int i = 0; i < VnSet.size() + 1; i++) {
                if (table[i][0].charAt(0) == X)
                    for (int j = 0; j < VtSet.size() + 1; j++) {
                        if (table[0][j].charAt(0) == a)
                            return table[i][j];
                    }
            }
            return "";
        }
    
        @Override
        public void insert(char X, char a, String s) {//插入
            if(a == '&')
                a = '$';
            for (int i = 0; i < VnSet.size() + 1; i++) {
                if (table[i][0].charAt(0) == X)
                    for (int j = 0; j < VtSet.size() + 1; j++) {
                        if (table[0][j].charAt(0) == a){
                            table[i][j] = s;
                            return;
                        }
                    }
            }
        }
    
        @Override
        public void displayLL() {// 对输入串(a,a)$ 输出 LL(1)分析过程
            Stack<Character> s = MyAnaStatck;
            System.out.printf("%23s", s );//输出第一列:分析栈
            System.out.printf("%13s", strInput.substring(Index));//输出第二列:输入串
            System.out.printf("%10s", MyAction);//输出第三列:动作
            System.out.println();
        }
    
        @Override
        public void ouput() {
            // 输出终结符的first集
            System.out.println("-------------------2.first集-------------------");
            for (Character c : VnSet) {
                HashSet<Character> set = MyfirstSet.get(c);
                System.out.printf("%10s",c + "  ->   ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------first集-------------------");
            // 输出任意符号串的first集
            System.out.println("-------------------firstX集-------------------");
            Set<String> setStr =  MyfirstSetX.keySet();
            for (String s : setStr) {
                HashSet<Character> set = MyfirstSetX.get(s);
                System.out.printf("%10s",s + "  ->   ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------firstX集-------------------");
            // 输出follow集
            System.out.println("-------------------3.follow集-------------------");
    
            for (Character c : VnSet) {
                HashSet<Character> set = MyfollowSet.get(c);
                System.out.print("Follow " + c + " : ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------follow集-------------------");
            //构造LL1文法预测分析表
            System.out.println("-------------------4.LL1预测分析表-------------------");
    
            for (int i = 0; i < VnSet.size() + 1; i++) {
                for (int j = 0; j < VtSet.size() + 1; j++) {
                    System.out.printf("%8s", table[i][j] + " ");
                }
                System.out.println();
            }
            System.out.println("-------------------LL1预测分析表-------------------");
        }
    }
    

    四、结果分析

    1、输入正确的源程序截图:
    将符号ε替换为&
    在这里插入图片描述

    输出结果截图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    2、输入错误的源程序截图:
    输入错误文法
    在这里插入图片描述
    输出结果截图:
    在这里插入图片描述
    3、总结(自己的心得体会、你编写的语法分析程序的优缺点)
    S->a|^|(T)
    T->SU
    U->,SU|ε

    • 优点:文法分析过程比较详细,任务整个完成过程是充实的,这个实验报告相当于对编译原理理论课的一次实践尝试,能收获很多课堂上面学不到的知识,同时也能巩固老师所教授的知识。

    • 缺点:在写程序的时候,卡在了空串那个点。最开始尝试直接在程序中定义文法时,ε能在程序中分析成功。后来在用读入文件的方式定义文法时,控制台出现乱码,这个点解决起来花了一点时间,最后决定将符号ε替换为&,程序才能运行成功。

    展开全文
  • 编译原理课设

    千次阅读 2019-09-23 06:08:52
    4.8、流程图   五、测试数据设计 输入串:#(((a,a),x,(a)),a)# 六、程序输出结果分析 七、设计重点难点分析 八、参考文献 九、附录 9.1、Main.class import analysestring.Analyse; import...

    一、课程设计内容

    1.1、前置条件:有效文法及正确的算符优先表

    1.2、功能需求:根据文法及算符优先表,实现算符优先分析过程,输入串采用教材133页习题2中(2)中的字符串(#(((a,a),x,(a)),a)#)。

    1.3、开发环境: Java(jdk1.8)

                    Windows 10

    二、数据结构设计

    2.1、类

    2.1.1、文法对象类

    public class Grammar {

        private String left;

        private String right;

        public Grammar(String l, String r) {

            this.left = l;

            this.right = r;

        }

        public String getLeft() {

            return left;

        }

        public String getRight() {

            return right;

        }

    }

    2.1.2、文法集合对象

    public class GrammarList {

        private List<Grammar> list = new ArrayList<>();

        private List<String> leftList = new ArrayList<>();

        private List<String> rightList = new ArrayList<>();

        public void addGrammar(Grammar grammar) {

            leftList.add(grammar.getLeft());

            rightList.add(grammar.getRight());

            list.add(new Grammar(grammar.getLeft(), grammar.getRight()));

        }

        public List<Grammar> getGrammarList() {

            return list;

        }

        public List<String> getLeftList() {

            return leftList;

        }

        public List<String> getRightList() {

            return rightList;

        }

    }

    2.2、全局变量

    2.2.1、当前操作符

    String signTemp

    2.2.2、符号栈

    Stack<String> signStack

    2.2.3、字符串栈

    Stack<String> opStack

    2.2.4、分析步骤计数

        int num

    三、程序总体设计

    public class Main {

        public static void main(String[] args) {

            Priority[][] matrix = MakeMatrix.getMatrix();

            Map<String, Integer> keyMap = MakeMatrix.getKeyMap();

                   // 1、输入字符串

            String str = "#(((a,a),x,(a)),a)#";  // ^ 用x代替

            String[] strings = str.split("");

                   // 2、创建文法

            Grammar grammar0 = new Grammar("S", "a");

            Grammar grammar1 = new Grammar("S", "x");

            Grammar grammar2 = new Grammar("S", "(R)");

            Grammar grammar3 = new Grammar("T", "S,T");

            Grammar grammar4 = new Grammar("T", "S");

            Grammar grammar5 = new Grammar("R", "T");

                   // 3、添加文法

            GrammarList list = new GrammarList();

            list.addGrammar(grammar0);

            list.addGrammar(grammar1);

            list.addGrammar(grammar2);

            list.addGrammar(grammar3);

            list.addGrammar(grammar4);

            list.addGrammar(grammar5);

                   // 4、算符优先分析

            Analyse runner = new Analyse();

            runner.analyse(list, matrix, keyMap, strings);

        }

    }

    四、详细设计

    4.1、向文法集合中添加文法

    public void addGrammar(Grammar grammar)

    4.2、获取文法集合

    public List<Grammar> getGrammarList()

    4.3、获取算符优先矩阵

    public static Priority[][] getMatrix()

    4.4、获取终结符对应行列

    public static Map<String, Integer> getKeyMap()

    4.5、进行算符优先分析

    GrammarList list 文法集合

    Priority[][] matrix 算符优先矩阵

    Map<String, Integer> keyMap 终结符行列号

    String[] strings 输入串

    public void analyse(GrammarList list, Priority[][] matrix, Map<String, Integer> keyMap, String[] strings)

    4.6、规约函数

    String now 规约串

    private boolean gy(String now, GrammarList list)

    4.7、打印信息

    Stack<String> opStack 字符串栈

    String signTemp 符号栈顶元素

    int index 分析步骤序号

    String action 分析动作(移进/归约)

    private void outputProcess(Stack<String> opStack, String signTemp, String[] strings, int index, String action)

    4.8、流程图

     

    五、测试数据设计

    输入串:#(((a,a),x,(a)),a)#

    六、程序输出结果分析

    七、设计重点难点分析

    八、参考文献

    九、附录

    9.1、Main.class

    import analysestring.Analyse;

    import enums.Priority;

    import grammar.Grammar;

    import grammar.GrammarList;

    import makematrix.MakeMatrix;

    import java.util.Map;

     

    public class Main {

        public static void main(String[] args) {

            Priority[][] matrix = MakeMatrix.getMatrix();

            Map<String, Integer> keyMap = MakeMatrix.getKeyMap();

            String str = "#(((a,a),x,(a)),a)#";  // ^ 用x代替

            String[] strings = str.split("");

     

            Grammar grammar0 = new Grammar("S", "a");

            Grammar grammar1 = new Grammar("S", "x");

            Grammar grammar2 = new Grammar("S", "(R)");

            Grammar grammar3 = new Grammar("T", "S,T");

            Grammar grammar4 = new Grammar("T", "S");

            Grammar grammar5 = new Grammar("R", "T");

     

            GrammarList list = new GrammarList();

            list.addGrammar(grammar0);

            list.addGrammar(grammar1);

            list.addGrammar(grammar2);

            list.addGrammar(grammar3);

            list.addGrammar(grammar4);

            list.addGrammar(grammar5);

     

            Analyse runner = new Analyse();

            runner.analyse(list, matrix, keyMap, strings);

        }

    }

    9.2、Grammar.class

    public class Grammar {

        private String left;

        private String right;

     

        public Grammar(String l, String r) {

            this.left = l;

            this.right = r;

        }

     

        public String getLeft() {

            return left;

        }

     

        public String getRight() {

            return right;

        }

    }

    9.3、GrammarList.class

    import java.util.ArrayList;

    import java.util.List;

     

    public class GrammarList {

        private List<Grammar> list = new ArrayList<>();

        private List<String> leftList = new ArrayList<>();

        private List<String> rightList = new ArrayList<>();

     

        public void addGrammar(Grammar grammar) {

            leftList.add(grammar.getLeft());

            rightList.add(grammar.getRight());

            list.add(new Grammar(grammar.getLeft(), grammar.getRight()));

        }

     

        public List<Grammar> getGrammarList() {

            return list;

        }

     

        public List<String> getLeftList() {

            return leftList;

        }

     

        public List<String> getRightList() {

            return rightList;

        }

    }

    9.4、Priority.class

    public enum Priority {

        NULL(0, "无关系"),

        SMALL(1, "小于"),

        EQUAL(2, "等于"),

        BIG(3, "大于");

     

        private int state;

        private String stateInfo;

     

        private Priority(int state, String stateInfo) {

            this.state = state;

            this.stateInfo = stateInfo;

        }

     

        public int getState() {

            return this.state;

        }

     

        public String getStateInfo() {

            return this.stateInfo;

        }

    }

    9.5、MakeMatrix.class

    import enums.Priority;

    import java.util.HashMap;

    import java.util.Map;

     

    public class MakeMatrix {

        private static Map<String, Integer> key = new HashMap<>();

     

        static {

            key.put("a", 0);

            key.put("x", 1);

            key.put("(", 2);

            key.put(")", 3);

            key.put(",", 4);

            key.put("#", 5);

        }

     

        private static Priority[][] operationMatrix = {

                {Priority.NULL, Priority.NULL, Priority.NULL, Priority.BIG, Priority.BIG, Priority.BIG},

                {Priority.NULL, Priority.NULL, Priority.NULL, Priority.BIG, Priority.BIG, Priority.BIG},

                {Priority.SMALL, Priority.SMALL, Priority.SMALL, Priority.EQUAL, Priority.SMALL, Priority.NULL},

                {Priority.NULL, Priority.NULL, Priority.NULL, Priority.BIG, Priority.BIG, Priority.BIG},

                {Priority.SMALL, Priority.SMALL, Priority.SMALL, Priority.BIG, Priority.SMALL, Priority.NULL},

                {Priority.SMALL, Priority.SMALL, Priority.SMALL, Priority.NULL, Priority.NULL, Priority.NULL}};

     

        public static Priority[][] getMatrix() {

            return operationMatrix;

        }

     

        public static Map<String, Integer> getKeyMap() {

            return key;

        }

    }

    9.6、Analyse.class

    import enums.Priority;

    import grammar.Grammar;

    import grammar.GrammarList;

     

    import java.util.List;

    import java.util.Map;

    import java.util.Stack;

     

    public class Analyse {

        private String signTemp = new String("");

        private Stack<String> signStack = new Stack<>();

        private Stack<String> opStack = new Stack<>();

        private int num = 0;

     

        public void analyse(GrammarList list, Priority[][] matrix, Map<String, Integer> keyMap, String[] strings) {

            for (int i = 0; i < strings.length; i++) {

                if (i == 0) {

                    opStack.push(strings[i]);

                    signStack.push(strings[i]);

                    signTemp = strings[i];

                    outputProcess(opStack, signTemp, strings, i + 1, "开始");

                    continue;

                }

                if (strings[i].equals(strings[0])) {

                    outputProcess(opStack, signTemp, strings, i, "结束");

                    System.out.println("程序结束");

                    break;

                }

                int v1 = keyMap.get(signTemp);

                int v2 = keyMap.get(strings[i]);

                if (matrix[v1][v2].equals(Priority.BIG)) { // 大于 则规约

                    String now = opStack.peek(); // 取出单字符大小的字符串

                    if (signStack.peek().equals(",")) {

                        if (now.equals("S")) {

                            // 用 T -> S 规约

                            outputProcess(opStack, signTemp, strings, i, "归约");

                            if (!gy(now, list)) {

                                break;

                            }

                            i--;

                            continue;

                        }

                        if (now.equals("T")) {

                            // 用T -> S,T 规约

                            outputProcess(opStack, signTemp, strings, i, "归约");

                            StringBuilder sb = new StringBuilder();

                            sb.append(opStack.pop());

                            sb.append(opStack.pop());

                            sb.append(opStack.peek());

                            if (!gy(new String(sb.reverse()), list)) {

                                break;

                            }

                            i--;

                            continue;

                        }

                    }

                    if (now.equals("T")) {

                        if (signTemp.equals("(")) {

                            outputProcess(opStack, signTemp, strings, i, "归约");

                            if (!gy(now, list)) {

                                break;

                            }

                            i--;

                            continue;

                        }

                    }

                    outputProcess(opStack, signTemp, strings, i, "归约");

                    if (!gy(now, list)) {

                        break;

                    }

                    i--;

                } else if (matrix[v1][v2].equals(Priority.SMALL)) { // 小于 则移进

     

                    outputProcess(opStack, signTemp, strings, i, "移进");

                    opStack.push(strings[i]);

                    signStack.push(strings[i]);

                    signTemp = signStack.peek();

                } else if (matrix[v1][v2].equals(Priority.EQUAL)) { // 去括号

                    StringBuilder sb = new StringBuilder();

                    while (!opStack.peek().equals("R")) {

                        outputProcess(opStack, signTemp, strings, i, "归约");

                        gy(opStack.peek(), list);

                    }

                    outputProcess(opStack, signTemp, strings, i, "移进");

                    opStack.push(strings[i]);

                    signStack.push(strings[i]);

                    signTemp = signStack.peek();

                    outputProcess(opStack, signTemp, strings, i + 1, "归约");

                    signStack.pop();

                    signTemp = signStack.peek();

                    sb.append(opStack.pop());

                    sb.append(opStack.pop());

                    sb.append(opStack.peek());

                    if (!gy(new String(sb.reverse()), list)) {

                        break;

                    }

                    continue;

                } else { // Priority.NULL  出错

                    System.out.println("规约出错  Priority.NULL");

                    break;

                }

            }

        }

     

        private boolean gy(String now, GrammarList list) {

            List<Grammar> grammars = list.getGrammarList();

            if (list.getRightList().contains(now)) {

                for (int j = 0; j < grammars.size(); j++) {

                    String right = grammars.get(j).getRight();

                    if (right.equals(now)) {

                        opStack.pop();

                        opStack.push(grammars.get(j).getLeft());

                        if (right.equals("T") || right.equals("S")) { // 当T->S 和R->T时  无关符号

                            break;

                        }

                        signStack.pop();

                        signTemp = signStack.peek();

                        break;

                    }

                }

                return true;

            } else {

                System.out.println("规约出错: 找不到规约串");

                return false;

            }

        }

     

        private void outputProcess(Stack<String> opStack, String signTemp, String[] strings, int index, String action) {

            if (num == 0) {

                System.out.println("步骤     栈                   当前符号            剩余符号             动作");

            }

            StringBuilder sbStack = new StringBuilder();

            StringBuilder sbStrs = new StringBuilder();

            Stack<String> temp = new Stack<>();

            while (!opStack.isEmpty()) {

                temp.push(opStack.pop());

            }

            while (!temp.isEmpty()) {

                sbStack.append(temp.peek());

                opStack.push(temp.pop());

            }

            for (int i = index; i < strings.length; i++) {

                sbStrs.append(strings[i]);

            }

            num++;

            System.out.printf("%-5d" + "    " + "%-20s" + "    " + "%-10s" + "    " + "%-20s" + "    " + action + "\n", num, sbStack, signTemp, sbStrs, action);

        }

    }

    转载于:https://www.cnblogs.com/GG-Bond/p/11220979.html

    展开全文
  • 编译原理课程设计词法分析任务书 5)参考文献: (1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社 (2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社 6)课程设计进度安排 1.准备阶段...

     

    编译原理课程设计词法分析任务书

     

     

    5)参考文献:

    (1)张素琴,吕映芝. 编译原理[M]., 清华大学出版社

    (2)蒋立源、康慕宁等,编译原理(第2版)[M],西安:西北工业大学出版社

    6)课程设计进度安排

    1.准备阶段(4学时):选择设计题目、了解设计目的要求、查阅相关资料

    2.程序模块设计分析阶段(4学时):程序总体设计、详细设计

    3.代码编写调试阶段(8学时):程序模块代码编写、调试、测试

    4.撰写论文阶段(4学时):总结课程设计任务和设计内容,撰写课程设计论文

     

      学生签名:              

          2019 年   5  月  9  日

     

    课程设计(论文)评审意见

    (1)学习态度(20分):优( )、良( )、中( )、一般( )、差( );

    (2)系统设计(20分):优(  )、良( )、中( )、一般( )、差( );

    (3)编程调试(20分):优( )、良( )、中( )、一般( )、差( );

    (4)回答问题(20分):优( )、良( )、中( )、一般( )、差( );

    (5)论文撰写(20分):优( )、良( )、中( )、一般( )、差( );

     

    评阅人:            职称:  讲师      

    2019  年  5  月 10  日

     

     

    中文摘要

    实现功能及实现:

      主要实现对文本中的程序进行词法分析,把程序中的单词分为五大类(基本保留字[1]、标识符[2]、常数[3]、运算符[4]、分隔符[5])并与相应的区域数字来对应输出.

      之前利用Java中的BufferedReader缓冲器对象来存储读取程序的文件,在刘立月老师指导下,较大程序文件的时有超时的情况,后更改成一行编译读取方式.利用两个异常处理,文件读取异常和输出异常时打印ERROR.

     

    背景和意义:

      词法分析的过程是线性的从头至尾扫描一遍,复杂度较低,易实现。能完成计算机翻译过程的关键阶段,它为后面的语法分析、语义分析做好准备,打好基础,以便快速地、高质量地生成目标语言程序。

     

     

    关键字: 词法分析、文件异常、目标语言程序

     

     


     

     

    一、课程设计任务及要求

    1.1、目的

      通过使用一个通用的能够自动根据正规表达式生成词法分析程序的工具程序设计一个简单语言的词法分析器,使学生充分理解课程理论内容和工具软件的使用技巧,掌握所涉及的典型数据结构,算法及方法,为今后在大型软件系统实践中设计性能优良的软件系统打下基础。

    1.2、任务与要求

      【基本要求】

       编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输            出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示)

    【测试数据】

    如源程序为C语言。输入如下一段:

    1 main(){
    2 
    3 int  a,b;
    4 
    5 a = 10;
    6 
    7      b = a + 20;
    8 
    9 }

     

    测试数据

     

     12,”main”)    (2,”a”)
     2 
     35,”(“)      (4,”=”)
     4 
     55,”)“)      (3,”10”)
     6 
     75,”{“)       (5,”;”)
     8 
     91,”int”)     (2,”b”)
    10 
    112,”a”)       (4,”=”)
    12 
    135,”,”)       (2,”a”)
    14 
    152,”b”)       (4,”+”)
    16 
    175,”;”)       (3,”20”)

     

     

     

    二、需求分析

    2.1、分析

      通过修改代码使得自动机能够更多的实现运算符号的识别功能,使用TINY语言调试一个程序,加深同学对词法分析的认识以及理解。另外,同时增强编写和调试程序的能力。

     

    2.2、问题解决

      对读取的文件进行预处理,从头到尾进行扫描,去除//和/*  */的内容,以及一些无用的、影响程序执行的符号如换行符、回车符、制表符等。但是千万注意不要在这个时候去除空格,因为空格在词法分析中有用,比如说int i=3;这个语句,如果去除空格就变成了“inti=3”,这样就失去了程序的本意,因此不能在这个时候去除空格。

     

    2.3、解决步骤

      对源文件从头到尾进行扫描了,从头开始扫描,主控程序主要负责系统建立一个文件保存四个表,这四个表分别存储关键字、运算符、界符、过滤符。而标识符和常数则用正则表达式判断。建立了多个布尔类,当系统读取代码时,用空格或制表符作为标志符,当遇到空格就输出之前检索的字符串进行判断(规定每个单词符号之间都有空格),判断字符串时,系统会通过顺序查找依次调用布尔类与之匹配来判断其属性并输出,如没有匹配成功,则说明所检索的字符串不合法,系统则会输出非法字符串。直到最后一个字符串匹配完毕之后系统结束。

     

     

     

     

    三、设计思路

    3.1、总体思路分析

      程序的关键点在于对给出一段程序中的各种单词的分离。在每段程序中,单词种类可以分为:关键字,分界符,算术运算符,关系运算符,标识符和常数。关键字的判断则是通过与已知数组中列出的元素进行对比,得出该单词是否为关键字;分解符,算术运算符,关系运算符的判断与接受到的字符进行比较,得出该字符是否为分解符,算术运算符或者为关系运算符。

     

    状态图

     

     

     

     

    图3-1-1:功能模块分解图

    总控程序流程图:

     

     

    图3-1-2:控制流程图

    3.2、设计原理

    主要任务如下:

    识别出输入的源程序中的单词,输出二元组形式的单词序列。

    删除无用的空白字符、回车符等没有实质意义的字符。

    图3-2:正规式和状态转换图

    实验步骤:

    PL/0语言文法的EBNF表示如下:

     

     1 <程序>::=begin<语句串>end
     2 
     3  
     4 
     5 <语句串>::=<语句>{;<语句>}
     6 
     7 <语句>::=<赋值语句>
     8 
     9  
    10 
    11 <赋值语句>::=ID:=<表达式>
    12 
    13  
    14 
    15 <表达式>::=<>{+<> | -<>}
    16 
    17  
    18 
    19 <>::=<因子>{*<因子> | /<因子>
    20 
    21  
    22 
    23 <因子>::=ID | NUM | (<表达式>

     

     

     

    3.3实现方法

    本次实验是设计词法分析器,其中核心函数是cifa(),分析的语言是PL/0,首先,采用循环遍历的方法读取用户输入的一段代码,跳过源程序中的空格字符,然后if语句配合switch语句对读入的代码挨个判断,最后以二元组的形式输出结果。

     

     

     

     

     

     

     

     

    四、详细设计

    4.1、项目设计步骤

    a)        创建存放识别程序文件

     

     

    图4-1:待编译程序文件test.txt

     

    b)       读取文件单词并存储

    读取文件test.txt文件:

           1 br = new BufferedReader(new FileReader("tests.txt")); 

     

    存放构成单词符号的字符串:

     1 public StringBuffer strToken = new StringBuffer(); 

     

    基本保留字(关键字)

     1 public String [] retainWord = new String[]{"int","if","else","return","main","void","while","break"}; 

     

    c)        识别不同程序单词

     

    基本保留字

    • 1 for(int i = 0;i < retainWord.length;i++){//是否为关键字,,是返回1
      2                      if(strToken.toString().equals(retainWord[i])){
      3 
      4                             return 1;
      5 
      6                      }
      7 
      8 }

       

     

    • 1 if(code == 1){//关键字
      2                      System.out.println("('"+1+"','"+strToken+"')");
      3 
      4               }

       

    标识符

     1 for(int i = 0;i < retainWord.length;i++){//是否为关键字,,是返回1
     2                      if(strToken.toString().equals(retainWord[i])){
     3 
     4                             return 1;
     5 
     6                      }
     7 
     8               }
     9 
    10               if(strToken.length() != 0){
    11 
    12                      ......
    13 
    14               }
    15 
    16               return 2;
    17 
    18        }
    19 
    20  
    21 
    22 else if(code == 2){//非数字,关键字
    23                      System.out.println("('"+2+"','"+strToken+"')");
    24 
    25               }
    26 
    27  
    28 
    29  
    30 
    31 常数
    32 
    33 if(strToken.charAt(0)>='0' && strToken.charAt(0)<='9'){//第一个是否为数字返回3
    34                             return 3;
    35 
    36                      }
    37 
    38  
    39 
    40 else if(code == 3){//数字
    41                      System.out.println("('"+3+"','"+strToken+"')");
    42 
    43               }

     

     

    运算符

     1 else if(ch == 43){
     2 Retract();                
     3 
     4 System.out.println("('"+4+"','"+(char) ch+"')");     
     5 
     6                         
     7 
     8 }else if(ch == 45){                                
     9 Retract();                              
    10 
    11 System.out.println("('"+4+"','"+(char) ch+"')");     
    12 
    13                         
    14 
    15 }else if(ch == 42){                                
    16 Retract();                              
    17 
    18 System.out.println("('"+4+"','"+(char) ch+"')");     
    19 
    20                         
    21 
    22 }else if(ch == 47){                                
    23 Retract();                              
    24 
    25 System.out.println("('"+4+"','"+(char) ch+"')");     

     

                               

    分隔符

     1 System.out.println("('"+5+"','"+(char) ch+"')");
     2        }else if((char) ch == '('){                      
     3 
     4               Retract();                          
     5 
     6 System.out.println("('"+5+"','"+(char) ch+"')");                      
     7        }else if((char) ch == ')'){                      
     8 
     9               Retract();                   
    10 
    11       
    12 
    13 System.out.println("('"+5+"','"+(char) ch+"')");                      
    14        }else if((char) ch == '{'){                      
    15 
    16               Retract();            
    17 
    18              
    19 
    20 System.out.println("('"+5+"','"+(char) ch+"')");                      
    21        }else if((char) ch == '}'){                      
    22 
    23               Retract();                   
    24 
    25       
    26 
    27 System.out.println("('"+5+"','"+(char) ch+"')");                      
    28        }else if((char) ch == ','){         

     

                 

    d)       语言单词编码

     

    表4-4:语言单词编码

     

    五、运行调试与分析讨论

    程序运行环境为Win10系统,在IDEA/ECLIPSE上运行

    运行结果分析如下:

    5.1、当在文本文件test.txt中输入文法:

     

    图5-1-1:类型号和单词输出结果

     

     

     

     

     

     

     

     

     

    5.2输出异常处理:

     

    a)        文件路径异常

     

     

    图5-1-2:获取程序文件异常

     

    b)       程序中未识别单词异常

     

     

    图5-1-3:不能识别程序单词报错

    六、设计体会与小结

     

    心得体会:

    这个程序实现了课设的所有要求(由于我是31号做第一题词法分析模拟,但同时实现了扩展功能对于注释的文字进行忽视编译),虽然可能还存在些不足,像之前刘立月老师提出的我的程序对于简短的程序是完全可以的,我的读取方式是对象全部读取.但是对于一些比较大的项目来进行对象读取时间比较长.于是在我的程序当中进行了一定量的修改,更改成行的读取.用编译原理的知识自己独立完成这样一个程序我觉得还不错了,毕竟做这样的课设可以学到不少东西.

     

    学习心得:

      一开始对编写词法分析毫无头绪,不知如何下手。上网查资料是我们迈开的第一步,然后查阅相关资料,小组里相互讨论帮助,在多次的调试和改进中终于把程序完成了。通过这次的程序实验我对编译原理这门课程有了进一步的深层次了解,而且在自已动手体验的情况下,更加透彻地理解了词法分析的过程。在设计过程中,要发扬团体合作的精神,互帮互助,共同进步。善于发问,善于思考。

     

    七、参考文献

     1 [1] 张素琴.编译原理. 北京:清华大学出版社,2005
     2 
     3 [2] 付京周.JAVA 程序设计语言. 北京:人民邮电出版社,2007
     4 
     5 [3]黄贤英,王珂珂.编译原理及实践教程.北京:清华大学出版社,2008
     6 
     7 [4]黄贤英,王珂珂,刘洁,曹琼.编译原理重点难点分析.习题解析·实验指导.北京:机械
     8 
     9 工业出版社,2008
    10 
    11 [5]陈媛,何波,涂晓红,涂飞算法与数据结构.北京:清华大学出版社,2005[4]刘恒洋,杨宏雨.算法与数据结构.北京:机械工业出版社,2010
    12 
    13 [6]陈火旺,《程序设计语言编译原理》(第3版),北京:国防工业出版社.2000.
    14 
    15 [7]美Alfred V. Aho Ravi Sethi Jeffrey D. Ullman著.李建中,姜守旭译.《编译原理》. 北京:机械工业出版社.2003.
    16 
    17 [8]美KennethC. Louden著.冯博琴等译.《编译原理及实践》.北京:机械工业出版社.2002.
    18 
    19 [9]金成植著.《编译程序构造原理和实现技术》.北京:高等教育出版社.2002.

     

     

    扫码公众号--回复“词法分析”获取源码:

     

     

     

    展开全文
  • 编译原理课设实验报告

    千次阅读 2015-12-31 00:31:38
    4.1 程序流程图  32  4.2 程序说明  32  4.3 实验结果  34 5. 结论 36 6. 参考文献 37 7. 收获、体会和建议 38 一. 概述  编译原理课程兼有很强的理论性和实践性,是计算机...
  • 编译原理-语法分析详解

    千次阅读 多人点赞 2020-12-20 20:57:58
    一文带你读懂语法分析(编译原理)一、前言二、前置知识三、自顶向下的语法分析1、自顶向下的分析会遇到的问题a. 二义性问题b. 回溯问题c. 左递归引起的无穷推导问题2、解决以上问题a. 二义性问题 一、前言   最近...
  • 编译原理复习总结及思维导图

    千次阅读 多人点赞 2020-02-11 23:48:37
    按照惯例,在每一书本学习后都会着手编制编译原理的总结资料,但在QQ群中无意中找到一篇《编译原理总结》的Word文件,感觉得很好,因此便将其整理出来并附上自己绘制的思维导图。由于文件里面没有作者具体信息,因此...
  • 编译原理学习基本概念汇总

    万次阅读 2016-01-29 10:15:26
    对于计算机专业的学生来说,肯定听说过或者上过一门课,叫做——编译原理,被称为计算机专业的天书,反正不管是学习这门课的时候,还是现在,我都是没搞懂其中的技术和知识。但就期末考试而言,提前做了几道题目,...
  • 1 编译程序的逻辑结构
  • 1.库的分类 根据链接时期的不同,库又有静态库和动态库之...所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。(TODO:链接动态库时链接阶段到底做了什么) 2 静态库和动态库的比较 链接静态库其...
  • 编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法。内容包括语言和文法、词法分析、语法分析、语法制导翻译、中间代码生成、存储管理、代码优化和目标代码生成。 编译原理是...
  • 为了更好的配合《编译原理》有关词法分析章节的教学 加深和巩固学生对于语法分析的了解和掌握 让学生进一步的认识PL/0语言的基础和简单的程序编写 使学生通过本实验能够扩大对pl/0的理解。 提高学生的上机和编程过程...
  • 文章目录《编译原理》课程设计实验报告书C-语言的语法描述系统设计系统亮点符号表的实现中间代码生成系统的总体结构主要功能模块的设计系统运行流程系统实现系统主要函数说明(主要功能、输入\输出、实现思想)...
  • 这是我做的编译原理简单优先文法判定和分析器的构造。 包括第一章 概述 3 1.1 项目背景 3 1.2 设计目的 3 1.3 实验环境与开发工具 3 1.4 C++语言 4 第二章 需求分析 5 2.1 问题陈述 5 2.1.1 简单优先文法 5 2.1.2 ...
  • 编译原理实验一 词法分析设计

    千次阅读 2019-11-27 21:41:29
    通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设 计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的 理解,并能正确地、熟练地运用。 二、实验内容 用 VC++/VB/JAVA ...
  • 文章目录一、概述二、基于 Flex 构造词法分析器2.1 需求描述2.2 编译流程2.3 Flex 代码三、手工构造词法分析器3.1 需求描述3.2 实现流程3.3 C++ 代码四、测试用例4.1 测试用例一4.1.1 代码输入4.1.2 词法分析结果4.2...
  • 中增加一个A,并把 AVALUE(A) 改为 RiR_iRi​ 3.4 代码生成算法 3.4.1 算法描述 总体流程 寄存器分配算法 3.4.2 算法举例 为基本块生成代码示例 四、DAG的目标代码 作用:重排中间代码,减少目标代码 算法: 构建 ...
  • 编译原理实验一:单词的词法分析程序设计 (注:这是我第一次尝试写博客,也是为了对自己的学习生活的一种记录,写的如果有不好的地方请大家帮忙提出来,我会坚持写下去哒!) 1.1实验内容 目的: 通过设计、编制、...
  • openwrt编译流程分析

    2021-02-18 16:18:57
    编译总体过程如下: 1.编译host工具 2.编译交叉工具链 3.编译内核模块 4.编译ipk 5.安装ipk到文件系统 6.编译内核 7.将内核和文件系统组合成最终binary 1. 编译host工具 虽然我们在开始编译前已经安装了...
  • 目录1、实验目的与内容2、程序总体设计思路和框架3、主要的数据结构和流程描述4、测试结果与说明5、实验收获与反思附录参考资料 1、实验目的与内容 输入:一个正则表达式(例如“(a|b)*abb”) 输出:对应的一个NFA...
  • 编译原理(1)词法分析程序(C++实现)

    万次阅读 多人点赞 2018-04-01 23:34:54
    这是关于编译原理的第一篇文章。本科阶段的教学与实际操作存在一些脱节的现象。比如词法编辑器你可以完全在不知道什么nfadfa啊之类东西情况下强行摸索出来,而书上和上课讲的却是各种状态转换之类的东西。还要去背...
  • 编译原理课程设计与实验安排1.1课程设计的基本要求和方法1 课程设计的目的编译原理课程是计算机科学与技术专业学生的重要基础课程。通过学习该课程,要求学生掌握编译原理的基本原理、方法和技术。《编译原理》课程...
  • 前言 编译原理词法分析器的实验作业,现记录如下: 一、实验目的 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析...
  • [编译原理]PL/0 编译器的设计与实现

    千次阅读 2020-04-21 16:09:38
    编译过程采用一趟扫描方式 以语法、语义分析程序为核心 词法分析程序和代码生成程序都作为一个过程,当语法分析需要读单词时就调用词法分析程序,而当语法、语义分析正确,需要生成相应的目标代码时,则调用代码...
  • 前言:表驱动LL(1)语法分析程序是本人在大三上学期的《编译原理》这门课程的课程设计选做题目,在这次的课程设计中,主要实现判断给定文法是否为LL(1)文法,若是,则给出其预测分析表及对给定输入串进行分析,判定...
  • 实验报告一:PL0语言编译器分析一、实验目的 通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码, 加深对编译阶段(包括词法分析、语法分析、语义分析、中间代码生成等)和编译系统软件结构的理解,并达到...
  • Android应用开发编译框架流程与IDE及Gradle概要

    万次阅读 多人点赞 2015-11-07 19:24:43
    1 背景建议阅读本文之前先...本文的核心就是下:关于Gradle的Android插件本文不会过多的说明,只给一个抛砖引玉的提示,详细使用参见文档API及Gradle配置,其实个性化的构建配置一般都是Gradle与Groovy的编写,与Andr
  • C++服务编译耗时优化原理及实践

    万次阅读 多人点赞 2020-12-10 19:59:00
    总第428篇2020年 第52篇大型C++工程项目,都会面临编译耗时较长的问题。不管是开发调试迭代、准入测试,亦或是持续集成阶段,编译行为无处不在,降低编译时间对提高研发效率来说具有非常...
  • 芯片设计流程 芯片的设计原理图

    万次阅读 多人点赞 2019-05-04 10:09:50
    芯片的具体设计流程又是什么?本文探讨的就是芯片在字面以外的意义,以及芯片是怎么被设计成的。 芯片 芯片,又称微电路(microcircuit)、微芯片(microchip)、集成电路(英语:integrated circuit, IC)。是指...
  • 一张解释典型编译程序结构框图

    千次阅读 2017-10-04 11:10:14
    编译程序结构框图

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,260
精华内容 5,304
关键字:

编译原理总体流程图