表达式语法分析——递归子程序法

简介: 表达式语法分析——递归子程序法

题目介绍

题目思路

题目给的表达式文法为:

  • E→TG
  • G→+TG | ε
  • T→FS
  • S→*FS | ε
  • F→(E) | i

例如:i+i*i是文法能生成的一个表达式,输出格式举例:

  • 0 E–>TG
  • 1 T–>FS
  • 2 F–>i
  • 3 S–>&
  • 4 G–>+TG
  • 5 T–>FS
  • 6 F–>i
  • 7 S–>*FS
  • 8 F–>i
  • 9 S–>&
  • 10 G–>&
  • accept

i@i不是文法能生成的表达式,输出格式举例:

  • 0 E–>TG
  • 1 T–>FS
  • 2 F–>i
  • 3 S–>&
  • 4 G–>&
  • error

(i+i*i不是文法能生成的表达式,存在括号不匹配的语法错误,输出格式举例:

  • 0 E–>TG
  • 1 T–>FS
  • 2 F–>(E)
  • 3 E–>TG
  • 4 T–>FS
  • 5 F–>i
  • 6 S–>&
  • 7 G–>+TG
  • 8 T–>FS
  • 9 F–>i
  • 10 S–>*FS
  • 11 F–>i
  • 12 S–>&
  • 13 G–>&
  • error

当你输入符号串的时候:

  • 首先要进行E()函数,该函数的意思是直接输出E所对应的文法E–>TG,可以直接跑到T()和G()
  • 对于T函数来说,直接根据题目输出T–>FS,来进入到F函数和S函数
  • 对于G函数来说,题目给的是G→+TG | ε,所以需要判断当前的字符是否为+号,如果当前字符为+的话,直接输出G–>+TG,num要加一位并且进入T函数和G函数,反之直接输出G–>&
  • 对于F函数来说,题目给的是F→(E) | i,所以需要判断当前的字符是否为i和(,如果当前是i的话,输出F–>i,如果是(的话,输出F–>(E),并且num++和进入E函数,这里需要再一次判断当前的字符串是否为(,防止只有右括号没有左括号的现象
  • 对于S函数来说,题目给的是S→*FS | ε如果当前字符串是*,直接输出**S→FS**,否则输出S→&*

易错点

  1. 在判断字符的时候忘记进行num++
  2. num++一定要在递归之前

代码

/*
author:苦酒
QQ:1793929520
blog:huangliangshuai.com
*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <stdio.h>
using namespace std;
char str[101];
int sum = 0;
int num = 0;
void E();
void T();
void G();
void F();
void S();
void E()
{
    cout<<sum++<<" "<<"E-->TG"<<endl;
    T();
    G();
}
void T()
{
    cout<<sum++<<" "<<"T-->FS"<<endl;
    F();
    S();
}
void G()
{
    if(str[num] == '+')
    {
        cout<<sum++<<" "<<"G-->+TG"<<endl;
        num++;
        T();
        G();
    }
    else
    {
        cout<<sum++<<" "<<"G-->&"<<endl;
    }
}
void F()
{
    if(str[num] == 'i')
    {
        cout<<sum++<<" "<<"F-->i"<<endl;
        num++;
    }
    else if(str[num] == '(')
    {
        cout<<sum++<<" "<<"F-->(E)"<<endl;
        num++;
        E();
        if(str[num] == ')')
        {
            num++;
        }
        else
        {
            printf("error\n");
            exit(0);
        }
    }
    else
    {
        printf("error\n");
        exit(0);
    }
}
void S()
{
    if(str[num] == '*')
    {
        cout<<sum++<<" "<<"S-->*FS"<<endl;
        num++;
        F();
        S();
    }
    else
    {
        cout<<sum++<<" "<<"S-->&"<<endl;
    }
}
int main()
{
    scanf("%s", str);
    E();
    if(str[num] != '#')
    {
        cout<<"error"<<endl;
    }
    else
    {
        cout<<"accept"<<endl;
    }
}
/***************************************************
User name: jk170631黄良帅
Result: Accepted
Take time: 0ms
Take Memory: 192KB
Submit time: 2019-11-19 19:24:50
****************************************************/


相关文章
|
6月前
|
C语言
C语言的条件表达式
C语言的条件表达式
77 1
|
存储 Unix 编译器
初始C语言(6)——详细讲解表达式求值以及其易错点
初始C语言(6)——详细讲解表达式求值以及其易错点
178 0
【编译原理】语法分析:从顶向下、最左推导
【编译原理】语法分析:从顶向下、最左推导
|
6月前
|
存储 程序员 C语言
C语言中的嵌套语句与Switch语句的深入解析
C语言中的嵌套语句与Switch语句的深入解析
87 1
|
5月前
|
自然语言处理 Java C++
递归下降子程序文法部分编写
`char`和`num dotdot num`的定义。如果遇到不匹配,原本计划调用`error`函数来报告错误,但在这个例子中,`error`函数并未实现。程序通过`main`函数获取用户输入并启动解析过程。
19 0
|
6月前
|
C语言
C语言函数嵌套与递归调用的深入解析
C语言函数嵌套与递归调用的深入解析
72 0
|
6月前
|
C语言
C语言if语句的关系表达式
C语言if语句的关系表达式
52 0
|
6月前
|
算法 Java C语言
C语言函数的递归
C语言函数的递归
31 0
|
自然语言处理 Java
Antlr实现任意四则运算表达式求值
上面语法就是四则运算的巴科斯范式定义(EBNF),可能对初学者有点难理解,其实就是一个递归定义,一个表达式可能是有多个子表达式构成,但子表达式的尽头一定是数字。 antlr可以用EBNF所定义的规则,将某个输入串解析为一颗抽象语法树(AST)。我们以表达式((3+3)*(1+4))/(5-3) 为例
165 0
|
算法 C语言
C语言函数递归练习详解
C语言函数递归练习详解