zoukankan      html  css  js  c++  java
  • 实验二 递归下降语法分析

    一、实验目的:

    利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

    编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

    二、实验原理

    每个非终结符都对应一个子程序。

    该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

    • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
    • 每遇到一个非终结符,则调用相应的子程序

    三、实验要求说明

    输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

    例如:

    输入begin a:=9;x:=2*3;b:=a+x end #

    输出success

    输入x:=a+b*c  end #

    输出‘end' error

    四、实验步骤

          1.待分析的语言的语法(参考P90)

          2.将其改为文法表示,至少包含

    –语句

    –条件

    –表达式

        E -> E+T | T

         T -> T*F | F

         F -> (E) | i

    3. 消除其左递归

      E->T+E'
      E'->+TE'|ε

      T->FT'

      T'->*FT'|ε

      F -> (E) | i

    4. 提取公共左因子

    5. SELECT集计算

    FIRST集:

    FIRST(E)={(,i}

    FIRST(E')={+,ε}

    FIRST(T)={(,i}

    FIRST(T')={*,ε}

    FIRST(F)={(,i}

    FOLLOW集:

    FOLLOW(E)={),#}

    FOLLOW(E')={),#}

    FOLLOW(T)={+,),#}

    FOLLOW(T')={+,),#}

    FOLLOW(F)={*,+,),#}

    SELECT集:

    SELECT(E→TE')={ ( , i }

    SELECT(E'→+TE')={+}

    SELECT(E'→ε)={),#}

    SELECT(T→FT')={ ( , i }

    SELECT(T'→*FT')={*}

    SELECT(T'→ε)={+,),#}

    SELECT(F→(E))={(}

    SELECT(F→i)={i}

    6. LL(1)文法判断

    此文法为LL(1)文法。

    7. 递归下降分析程序

    词法分析程序Check.java:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    
    public class Check {
        public boolean check(String s2) {
            if ("".equals(s2)) {
                return false;
            }
    
    
            Map<Integer, String> map = new HashMap<Integer, String>();
            map.put(1, "begin");
            map.put(2, "if");
            map.put(3, "then");
            map.put(4, "while");
            map.put(5, "do");
            map.put(6, "end");
            map.put(13, "+");
            map.put(14, "-");
            map.put(15, "*");
            map.put(16, "/");
            map.put(17, ":");
            map.put(18, ":=");
            map.put(20, "<");
            map.put(21, "<>");
            map.put(22, "<=");
            map.put(23, ">");
            map.put(24, ">=");
            map.put(25, "=");
            map.put(26, ":");
            map.put(27, "(");
            map.put(28, ")");
            map.put(0, "#");
    
            char s3[] = s2.toCharArray();
    
            for (int i = 0; i < s3.length; i++) {
    
                int news3 = (int) s3[i];
    
                boolean flag1 = false;
                if (((news3 >= 65) && (news3 <= 90))
                        || ((news3 >= 97) && (news3 <= 122))) {
                    while (((news3 >= 65) && (news3 <= 90))
                            || ((news3 >= 97) && (news3 <= 122))
                            || (news3 >= 48 && news3 <= 57)) {
    
                        flag1 = true;
                        i++;
                        if (i>=s3.length) {
                            break;
                        }
                        news3 = (int) s3[i];
                    }
                    i--;
                }
    
    
                news3 = (int) s3[i];
                boolean flag2 = false;
                while (news3 >= 48 && news3 <= 57) {
                    i++;
                    if (i>=s3.length) {
                        break;
                    }
                    news3 = (int) s3[i];
                    flag2 = true;
                }
                if (flag2)  i--;
    
                boolean flag3 = false;
                boolean flag5 = true;
                if (map.containsValue(""+s3[i])) {
                    i++;
                    flag3 = true;
                    if (i>=s3.length) {
                        i--;
                        break;
                    }
                    if (map.containsValue(""+s3[i])) {
                        String x=""+s3[i-1]+s3[i];
                        if (map.containsValue(x)) {
                            continue;
                        }else {
                            flag5=false;
                        }
                    }
                    i--;
                }
                if (flag5==false) return false;
    
    
                news3 = (int) s3[i];
                boolean flag4 = false;
                String zfc = "";
                if (news3 == 34) {
                    flag4 = true;
                    zfc += s3[i];
                    i++;
                    news3 = (int) s3[i];
                    while (news3 != 34) {
                        zfc += s3[i];
                        i++;
                        if (i>=s3.length) {
                            i--;
                            break;
                        }
                        news3 = (int) s3[i];
                    }
                    if(news3!=34) return false;
    
                }
    
                if (news3 == 32) {
                    continue;
                }
    
                if (flag1||flag2||flag3||flag4) {
    
                }
                else {
                    return false;
                }
            }
    
            return true;
        }
    }

    语法分析程序Work.java:

    import java.util.Scanner;
    
    import static java.lang.System.exit;
    
    public class Work {
        static int index=0;
        static Scanner sc = new Scanner(System.in);
        static String s2 = sc.nextLine();
        static char s3[] = s2.toCharArray();
        public static void main(String[] args) throws Exception {
    
            Check ck = new Check();
    
            if (ck.check(s2)&&s2.endsWith("#")) {
                ParseE();
            } else {
                System.out.print("输入有误!");
            }
        }
        static void ParseE(){
            ParseT();
            ParseE1();
        }
    
        private static void ParseE1() {
            switch (s3[index]){
                case '+':
                    index+=1;
                    ParseT();
                    ParseE1();
                    break;
                case  '#':
                    break;
                case ')':
                    index+=1;
                    break;
                default:
                    System.out.println("synax error!");
                    exit(0);
                    break;
            }
        }
    
        private static void ParseT1() {
            switch (s3[index]){
                case '*':
                    index+=1;
                    ParseF();
                    ParseT1();
                    break;
                case  '#':
                    break;
                case ')':
                    index+=1;
                    break;
                case  '+':
                    break;
                default:
                    System.out.println("synax error!");
                    exit(0);
                    break;
            }
        }
    
        private static void ParseF() {
            switch (s3[index]){
                case '(':
                    index+=1;
                    ParseE();
                    break;
                case  'i':
                    index+=1;
                    break;
                default:
                    System.out.println("synax error!");
                    exit(0);
            }
        }
    
        private static void ParseT() {
            ParseF();
            ParseT1();
        }
    }

    结果:

     

  • 相关阅读:
    hdu 1873 看病要排队
    母函数详解
    【RDMA】无损网络和PFC(基于优先级的流量控制)
    图解Linux网络包接收过程
    结对编程 <==> 断背山?
    CMPP和SMPP协议比较
    Berkerly DB、SQL Server的性能比较
    使用Berkeley DB遇到问题了
    重新学习C语言
    超长短信的处理办法
  • 原文地址:https://www.cnblogs.com/ccla/p/11934265.html
Copyright © 2011-2022 走看看