实验二 递归下降语法分析

一、实验目的:

利用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();
    }
}

结果:

 

 

 

 

 

 

 

posted on 2019-11-28 13:55  ccl666  阅读(428)  评论(0编辑  收藏  举报