编译原理实验二 LL(1)分析法

实验二 LL(1)分析法

通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区 别和联系。使学生了解语法分析的功能,掌握语法分析程序设计的原理和构造方 法,训练学生掌握开发应用程序的基本方法。有利于提高学生的专业素质,为培 养适应社会多方面需要的能力。

二、实验内容

  •   根据某一文法编制调试 LL ( 1 )分析程序,以便对任意输入的符号串 进行分析。

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

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

    三、 LL(1)分析法实验设计思想及算法

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

13

四、实验要求

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 输出的格式如下:

14

五、实验步骤

1、根据流程图编写出各个模块的源程序代码上机调试。
2、 编制好源程序后,设计若干用例对系统进行全面的上机测试,并通过所设计 的 LL(1)分析程序;直至能够得到完全满意的结果。
3、书写实验报告 ;实验报告正文的内容:

  •   写出 LL(1)分析法的思想及写出符合 LL(1)分析法的文法。

  •   程序结构描述:函数调用格式、参数含义、返回值描述、函数功能;函数

    之间的调用关系图。

  •   详细的算法描述(程序执行流程图)。

  •   给出软件的测试方法和测试结果。
    实验总结 (设计的特点、不足、收获与体会)。

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Q2 {

    StringBuilder input = new StringBuilder();
    Deque<Character> stack = new LinkedList<>();

    void start() throws IOException {
        InputStreamReader reader = new InputStreamReader(Q2.class.getResourceAsStream("Q2"));
        for(int ch; (ch = reader.read()) != -1; ){
            input.append((char)ch);
        }

        stack.add('#');
        stack.add('E');

        print("");

        char X = stack.removeLast(); char a = input.charAt(0);

        while(true){
            if(X == '#' && a == '#'){
                print("SUCCESS");
                break;
            }else if(X != a){
                String s = M.get(X) == null ? null : M.get(X).get(a);
                if(s == null){
                    print("ERROR");
                    break;
                }else {
                    if (!"e".equals(s)) {
                        s = new StringBuilder(s).reverse().toString();
                        for (int i = 0; i < s.length(); i++) {
                            stack.add(s.charAt(i));
                        }
                    }
                    print("");
                    X = stack.removeLast();
                }
            }else{
                input.deleteCharAt(0); a = input.charAt(0);
                print("");
                X = stack.removeLast();
            }
        }
    }

    void print(String msg){
        if("ERROR".equals(msg)){
            System.out.println("ERROR");
        }else if("SUCCESS".equals(msg)){
            System.out.println("SUCCESS");
        }else {
            System.out.println(stack.toString() + '\t' + input.toString());
        }
    }

    static String[][] production = new String[][] {{"F", "(E)", "i"}, {"S", "e", "*FS", "/FS"}, {"T", "FS"}, {"G", "e", "+TG", "-TG"}, {"E", "TG"}};

    static Map<Character, Set<Character>> FIRST = new HashMap<>();
    static Map<Character, Set<Character>> FOLLOW = new HashMap<>();

    static Map<Character, Map<Character, String>> M = new HashMap<>();

    public static void main(String[] args) throws IOException {
        FIRST.put('F', new HashSet<>()); FOLLOW.put('F', new HashSet<>());
        FIRST.put('S', new HashSet<>()); FOLLOW.put('S', new HashSet<>());
        FIRST.put('T', new HashSet<>()); FOLLOW.put('T', new HashSet<>());
        FIRST.put('G', new HashSet<>()); FOLLOW.put('G', new HashSet<>());
        FIRST.put('E', new HashSet<>()); FOLLOW.put('E', new HashSet<Character>(){{ add('#'); }});

        M.put('E', new HashMap<>());
        M.put('G', new HashMap<>());
        M.put('T', new HashMap<>());
        M.put('S', new HashMap<>());
        M.put('F', new HashMap<>());

        for(String[] array : production){
            char left = array[0].charAt(0);
            for(int i = 1; i < array.length; i++){
                String s = array[i];
                if(Character.isUpperCase(s.charAt(0))){
                    for(int j = 0; j < s.length() && Character.isUpperCase(s.charAt(j)); j++){
                        FIRST.get(left).addAll(FIRST.get(s.charAt(j)));
                        if(!FIRST.get(s.charAt(j)).contains('e')){
                            break;
                        }
                        if(j == s.length() - 1){
                            FIRST.get(left).add('e');
                        }
                    }
                }else{
                    FIRST.get(left).add(s.charAt(0));
                }
            }
        }

        production = new String[][] {{"F", "(E)", "i"}, {"E", "TG"}, {"G", "e", "+TG", "-TG"}, {"S", "e", "*FS", "/FS"}, {"T", "FS"}};
        for(String[] array : production){
            char left = array[0].charAt(0);
            for(int i = 1; i < array.length; i++){
                String s = array[i];
                for(int j = 0; j < s.length(); j++){
                    char ch = s.charAt(j);
                    if(Character.isUpperCase(ch)){
                        if(j == s.length() - 1){
                            FOLLOW.get(ch).addAll(FOLLOW.get(left));
                            break;
                        }
                        Set<Character> temp = new HashSet<>();
                        for(int k = j + 1; k < s.length(); k++){
                            if(Character.isUpperCase(s.charAt(k))){
                                temp.addAll(FIRST.get(s.charAt(k)));
                            }else{
                                temp.add(s.charAt(k));
                                break;
                            }
                            if(!FIRST.get(s.charAt(k)).contains('e')){
                                break;
                            }
                            if(k == s.length() - 1){
                                FOLLOW.get(ch).addAll(FOLLOW.get(left));
                            }
                        }
                        temp.remove('e');
                        FOLLOW.get(ch).addAll(temp);
                    }
                }
            }
        }

        for(String[] array : production){
            char left = array[0].charAt(0);
            for(int i = 1; i < array.length; i++){
                String s = array[i];
                if(Character.isUpperCase(s.charAt(0))){
                    Set<Character> temp = new HashSet<>();
                    for(int j = 0; j < s.length(); j++){
                        temp.addAll(FIRST.get(s.charAt(j)));
                        if(!FIRST.get(s.charAt(j)).contains('e')){
                            temp.remove('e');
                            break;
                        }
                    }
                    for(Character ch : temp){
                        if(ch != 'e') M.get(left).put(ch, s);
                    }
                    if(temp.contains('e')){
                        for(Character ch : FOLLOW.get(left)){
                            M.get(left).put(ch, "e");
                        }
                    }
                }else if(s.charAt(0) == 'e'){
                    for(Character ch : FOLLOW.get(left)){
                        M.get(left).put(ch, "e");
                    }
                }else{
                    M.get(left).put(s.charAt(0), s);
                }
            }
        }

        Q2 q2 = new Q2();
        q2.start();
    }
}

 

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值