编程语言
首页 > 编程语言> > 编译原理学习笔记 4.3 递归下降子程序法

编译原理学习笔记 4.3 递归下降子程序法

作者:互联网

前言

参考课上PPT内容。 该学习笔记目前仅打算个人使用。
后续会进一步整理,包括添加笔记内容,标明参考资料。

更新中。。。

跳过目录

目录

一、递归下降子程序法(递归下降分析法)

具体做法:

例:文法G[E]:

E → UV
U → …
V → …
在这里插入图片描述
注:

例:文法G[Z]

Z → ( U ) | aUb
U → dZ | Ud | e

1、检查并改写文法

Z → ( U ) | aUb
U → ( dZ | e ) { d }

注:Z → ( U ) 与 U → ( dZ | e ) 中括号意义并不一样,前者是终结符,后者是元语言符号。

改写后无左递归且首符集不相交:

2、检查文法的递归性

Z ⇒ …U… ⇒ …Z…,∴ Z ⇒ + \stackrel{+}{\Rightarrow} ⇒+ …Z…
U ⇒ …Z… ⇒ …U…,∴ U ⇒ + \stackrel{+}{\Rightarrow} ⇒+ …U…

因此, Z和U的分析程序可以编成递归子程序

3、算法框图

在这里插入图片描述
在这里插入图片描述
说明:

例:文法:

<语句> → <变量> := <表达式> | IF <表达式> THEN <语句> | IF <表达式> THEN <语句> ELSE <语句>
<变量> → i | i ‘[’<表达式>’]’
<表达式> → <项> | <表达式> + <项>
<项> → <因子> | <项> * <因子>
<因子> → <变量> | ‘(’<表达式>’)’

改写文法:
<语句> → <变量> := <表达式> | IF <表达式> THEN <语句> [ ELSE <语句> ]
<变量> → i [ ‘[’<表达式>’]’ ]
<表达式> → <项> { + <项> }
<项> → <因子> { * <因子> }
<因子> → <变量> | ‘(’<表达式>’)’

语法分析程序所要调用的子程序:

void main() // 分析主程序
{
    getsym();    // 预读一个符号
    statement(); // 调用<语句>的分析子程序
}

void statement() // <语句>的分析子程序
{
    if (sym == "IF") // 判断是否是条件语句
    {
        getsym(); // 预读一个符号
        expr();   // 调用<表达式>分析子程序
        if (sym != "THEN")
            error();
        else
        {
            getsym();    // 预读一个符号
            statement(); // 调用<语句>的分析子程序
            if (sym == "ELSE")
            {
                getsym();    // 预读一个符号
                statement(); // 调用<语句>的分析子程序
            }
        }
    }
    else
    {
        var(); // 调用<变量>的分析子程序
        if (sym != ":=")
            error();
        else
        {
            getsym(); // 预读一个符号
            expr();   // 调用<表达式>的分析子程序
        }
    }
    printf("it is a statement.\n"); // 打印分析结论
}

void var() // <变量>的分析子程序
{
    if (sym != "i")
        error();
    else
    {
        getsym(); // 预读一个符号
        if (sym == "[")
        {
            getsym(); // 预读一个符号
            expr();   // 调用<表达式>的分析子程序
            if (sym != "]")
                error();
            else
                getsym(); // 预读一个符号
        }
    }
    printf("it is a variable\n"); // 打印分析结论
}

void expr() // <表达式>的分析子程序
{
    term(); // 调用<项>的分析子程序
    while (sym == "+")
    {
        getsym(); // 预读一个符号
        term();   // 调用<项>的分析子程序
    }
    printf("it is an expression\n"); // 打印分析结论
}

void term() // <项>的分析子程序
{
    factor(); // 调用<因子>的分析子程序
    while (sym == "*")
    {
        getsym(); // 预读一个符号
        factor(); // 调用<因子>的分析子程序
    }
    printf("it is a term\n"); // 打印分析结论
}

void factor() // <因子>的分析子程序
{
    if (sym == "(")
    {
        getsym(); // 预读一个符号
        expr();   // 凋用<表达式>的分析子程序
        if (sym != ")")
            error();
        else
            getsym(); // 预读一个符号
    }
    else
        var();                  // 调用<变量>的分析子程序
    printf("it is a factor\n"); // 打印分析结论
}

void error() // 出错处理程序
{
    printf("syntex error!\n"); // 报告错误
}

例:分析

if (i+i) then i:=i*i+i else i[i]:=i+i[i*i]*(i+i)

标签:调用,4.3,递归,getsym,sym,预读,程序法,子程序
来源: https://blog.csdn.net/weixin_45755666/article/details/112238379