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

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

题目介绍

题目思路

题目给的表达式文法为:

  • 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
****************************************************/


相关文章
【编译原理】语法分析:从顶向下、最左推导
【编译原理】语法分析:从顶向下、最左推导
|
21天前
|
C语言
【C语言】逻辑操作符详解 - 《真假美猴王 ! 》
C语言中有三种主要的逻辑运算符:逻辑与(`&&`)、逻辑或(`||`)和逻辑非(`!`)。这些运算符用于执行布尔逻辑运算。
62 7
|
7月前
|
存储 程序员 C语言
C语言中的嵌套语句与Switch语句的深入解析
C语言中的嵌套语句与Switch语句的深入解析
109 1
|
6月前
|
自然语言处理 Java C++
递归下降子程序文法部分编写
`char`和`num dotdot num`的定义。如果遇到不匹配,原本计划调用`error`函数来报告错误,但在这个例子中,`error`函数并未实现。程序通过`main`函数获取用户输入并启动解析过程。
26 0
|
自然语言处理 Java
Antlr实现任意四则运算表达式求值
上面语法就是四则运算的巴科斯范式定义(EBNF),可能对初学者有点难理解,其实就是一个递归定义,一个表达式可能是有多个子表达式构成,但子表达式的尽头一定是数字。 antlr可以用EBNF所定义的规则,将某个输入串解析为一颗抽象语法树(AST)。我们以表达式((3+3)*(1+4))/(5-3) 为例
178 0
|
C语言
C语言例题讲解(if语句,循环语句,函数)
C语言例题讲解(if语句,循环语句,函数)
100 0
栈在求值表达式中的应用
栈在求值表达式中的应用
|
存储 Java 开发者
Java基础语法:变量、数据类型、运算符、条件语句和循环结构详解
Java基础语法:变量、数据类型、运算符、条件语句和循环结构详解
247 0
|
存储 Unix 编译器
表达式求值过程中会发生哪些隐藏的变化?求值顺序又由什么决定?——详解C表达式求值中的隐式类型转换,算术转换问题,以及操作符的属性
表达式求值过程中会发生哪些隐藏的变化?求值顺序又由什么决定?——详解C表达式求值中的隐式类型转换,算术转换问题,以及操作符的属性
170 0
|
算法 Scala
第2章 控制结构和函数
第2章 控制结构和函数
502 0