编译原理 递归下降分析法 First,Follow集合以及预测分析表

本文以浅显易懂的方式解释了文法的First和Follow集合的求法,并通过示例详细说明。接着,介绍了如何构建预测分析表,并提供了一个递归下降分析程序的实现,用于判断输入字符串是否符合文法规则。通过实例运行展示了程序的输出,帮助读者更好地理解和应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看例子:

设有文法:
E -> TE’
E’->+E|ε
T->FT’
T’->T|ε
F->PF’
F’->F’|ε
P->(E)|a|b|^

关于First,Follow集合以及预测分析表的求法

首先看了书和网上的资料,第一眼就是看不懂,接下来让我以白话的形式来分享一下

First和Follow集合

First集合的求法:

看一下例子我们应该能直接明白了:
首先看表达式E->TE’, 它的First(E)就是First(T),没懂?,不要紧,我在举个例子,这次我们看表达式 P->(E)|a|b|^, 它的First(.P)就是{(,a,b,^}(这里用.P代表下P啊),咱们再来最后一个例子,看表达式T’->T| ε, 它的First(T’)就是{FIrst(T),ε}.

我相信很多人都已经发现规律了,First的求法就是将后面式子的第一位加进去(如果有多种情况,则需要都取一下式子的第一位,如上面的First(.p)),如果是非终结符就把这个非终结符的First集合加进去,如果是终结符,直接加入终结符就行.

Follow集合的求法

首先要将#加入文法开头的Follow集合中,此题中E是文法集合,所以要将#加入Follow(E)中。
其次,设有表达式a->bcd
1.如果First(d)包含ε,那么就将Follow(a)的元素加入Follow(.c)中.d可以不存在.即a->bc,此时也要将Follow(a)的元素加入Follow(.c)中
2.将First(d)中除ε外的元素加入Follow(.c)中

预测分析表

这个我建议去看一下这个博客的末尾处,我就是看了这个一下就懂了,切记:如果看不懂定义,结合表看就懂了
https://blog.youkuaiyun.com/qq_41731283/article/details/106448620

递归下降分析程序

总体来说这个程序并不难,首先要知道我们的目的,我们的目的是输入一个字符串,然后判断能不能从E推出这个表达式,直接看代码,我相信各位一看就能懂.

package LeeCode;

import java.util.Scanner;

public class DiGuiRecursiveAnalysis {

    static String word;//输入的字符串

    static int index = 0;//用来记录目前准备匹配的字符的位置

    public void error() {//如果匹配错误,输出不合法的,然后终止程序,不再进行匹配
        System.out.println("不合法的!");
        System.exit(0);
    }




    //E->TE'
    public void E() {
        System.out.println("E->TE'");

        T();

        E1();



    }

    //E'->+E|null
    public void E1() {
        if (word.charAt(index) == '+') {
            index++;

            System.out.println("E'->+E");


            E();

        } else {
            System.out.println("E'->ε");
        }
    }

    // T->FT'
    private void T() {
        System.out.println("T->FT'");

        F();
        T1();
    }



    //  T'->T|null
    private void T1() {
    /*
    这里的if我要说一下,为什么条件是这些呢,因为我们First(T')中的元素是这些加上ε.然而我们要执行T1->ε这步最后得到的就是ε元素,反正执行T1->T这步最后可以得到该if中的元素,所以如果想执行T1->T这步,则需要匹配是不是这些元素
	*/
        if (word.charAt(index) == '('||word.charAt(index) == 'a'||word.charAt(index) == 'b'||word.charAt(index) == '&') {
            System.out.println("T'->T");
            T();
        } else{
            System.out.println("T'->ε");


        }




    }

    // F->PF'
    private void F() {
        System.out.println("F->PF'");

        P();
        F1();

    }

    //F'->*F'|null
    private void F1() {
        if (word.charAt(index) == '*') {
            index++;
            System.out.println("F'->*F'");

            F1();
        } else {
            System.out.println("F'->ε");


        }
    }

    //P->(E)|a|b|&
    private void P() {

        if (word.charAt(index) == '(') {
            index++;

            E();

            if (word.charAt(index) == ')') {
                index++;

                System.out.println("P->(E)");

            } else {
                error();
            }
        } else if (word.charAt(index) == 'a') {

            index++;

            System.out.println("P->a");
        }else if (word.charAt(index) == 'b') {
            index++;

            System.out.println("P->b");
        }else if (word.charAt(index) == '&') {
            index++;

            System.out.println("P->&");
        } else {
            error();
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        System.out.print("请输入字符串(以#结尾)");
        word = input.nextLine();

        if (word.charAt(word.length()-1)!='#'){
            System.out.println("输入的不符合要求,要以#结尾!");
            System.exit(0);
        }



        DiGuiRecursiveAnalysis parse = new DiGuiRecursiveAnalysis();
        parse.E();
        System.out.println("分析成功");//因为我程序如果判断出错误就终止了,所如果没有终止的话就代表成功了.直接输出即可.

    }

}



运行截图:
1.
在这里插入图片描述
2.
在这里插入图片描述
如有错误请指出,一起学习,一起进步!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值