表达式语法分析——预测分析法

表达式语法分析——预测分析法
Time Limit: 1000 ms Memory Limit: 65536 KiB
Submit Statistic
Problem Description

预测分析法是自顶向下分析的一种方法,一个预测分析程序是由三个部分组成:
(1) 预测分析程序
(2) 先进后出栈
(3) 预测分析表
现给出表达式文法:
E→TG
G→+TG | ε
T→FS
S→*FS | ε
F→(E) | i
该表达式文法是LL(1)文法,其预测分析表为:
请根据该预测分析表构造预测分析程序,完成对表达式的语法分析,对给定的输入串,判断其是否为合法表达式,给出所使用的产生式序列。

Input

给定输入串(长度不超过50个符号,以#号结束,符号保证是终结符或#)。
例如:
i+ii# 是合法表达式
i+i
(i+i)# 是合法表达式
ii+ii# 不是合法表达式
i
(i+i# 不是一个合法的表达式。
Output

要求输出分析过程中使用的所有产生式,产生式按使用顺序各占一行,每行有两个数据,使用顺序号(从1开始编号)及产生式本身,中间用一个空格分开,最后一行表示语法分析是否成功结束,如果成功分析结束输出acc!,表示该输入串是合法表达式,否者输出error!,表示该输入串不是合法表达式。
注:其中^符号代表文法中的ε符号。
针对输入串i+i*i#,因为分析过程使用了11次产生式,且该输入串是合法表达式,输出如下:
1 E->TG
2 T->FS
3 F->i
4 S->^
5 G->+TG
6 T->FS
7 F->i
8 S->FS
9 F->i
10 S->^
11 G->^
acc!
针对输入串i
(i+i#,因为分析过程使用了14次产生式后,发现语法错误,该输入串不是合法表达式,输出如下:
1 E->TG
2 T->FS
3 F->i
4 S->*FS
5 F->(E)
6 E->TG
7 T->FS
8 F->i
9 S->^
10 G->+TG
11 T->FS
12 F->i
13 S->^
14 G->^
error!
Sample Input

i+i*i#
Sample Output

1 E->TG
2 T->FS
3 F->i
4 S->^
5 G->+TG
6 T->FS
7 F->i
8 S->*FS
9 F->i
10 S->^
11 G->^
acc!
Hint

Source

#include <iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#define STACK_INIT_SIZE 100//初始空间分配量
using namespace std;
typedef char ElemType;
typedef struct
{
    ElemType *base;
    ElemType *top;//top在栈顶元素的上一个
}SqStack;
void initStack(SqStack &S)//值传递,引用传递,指针传递
{
    S.base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    S.top = S.base;
}
void Push(SqStack &S, ElemType e)
{
    *S.top++ = e;//先运算再加加
}
void Pop(SqStack &S, ElemType &e)
{
    e = *--S.top;//先减减再运算
}
ElemType get_top(SqStack &S)
{
    ElemType e;
    e = *(S.top-1);
    return e;
}
SqStack S;
ElemType e;
string str;
int i=0;
void E();
void G();
void T();
void S1();
void F();
int count=1;


void E()
{
    if(str[i]=='i'||str[i]=='(')
    {
        cout<<count<<" "<<"E->TG"<<endl;
        count++;
        Pop(S, e);
        Push(S, 'G');
        Push(S, 'T');
    }
    else
    {
        cout<<"error!"<<endl;
        exit(0);
    }
}
void T()
{
    if(str[i]=='i'||str[i]=='(')
    {
        cout<<count<<" "<<"T->FS"<<endl;
        count++;
        Pop(S, e);
        Push(S, 'S');
        Push(S, 'F');
    }
    else
    {
        cout<<"error!"<<endl;
        exit(0);
    }
}
void F()
{
    if(str[i]=='i')
    {
        cout<<count<<" "<<"F->i"<<endl;
        count++;
        Pop(S, e);
        Push(S, 'i');
    }
    else if(str[i]=='(')
    {
        cout<<count<<" "<<"F->(E)"<<endl;
        count++;
        Pop(S, e);
        Push(S, ')');
        Push(S, 'E');
        Push(S, '(');
    }
    else
    {
        cout<<"error!"<<endl;
        exit(0);
    }

}
void G()
{
    if(str[i]=='+')
    {
        cout<<count<<" "<<"G->+TG"<<endl;
        count++;
        Pop(S, e);
        Push(S, 'G');
        Push(S, 'T');
        Push(S, '+');
    }
    else if(str[i]==')'||str[i]=='#')
    {
        cout<<count<<" "<<"G->^"<<endl;
        count++;
        Pop(S, e);
    }
    else
    {
        cout<<"error!"<<endl;
        exit(0);
    }
}
void S1()
{
    if(str[i]=='*')
    {
        cout<<count<<" "<<"S->*FS"<<endl;
        count++;
        Pop(S, e);
        Push(S, 'S');
        Push(S, 'F');
        Push(S, '*');
    }
    else if(str[i]=='+'||str[i]==')'||str[i]=='#')
    {
        cout<<count<<" "<<"S->^"<<endl;
        count++;
        Pop(S, e);
    }
    else
    {
        cout<<"error!"<<endl;
        exit(0);
    }
}
int main()
{
    cin>>str;
    initStack(S);
    Push(S, '#');
    Push(S, 'E');
    while(1)
    {
        char b = get_top(S);
        char a = str[i];
        if(b==a&&b=='#')
        {
            break;
        }
        else if(b==a)
        {
            Pop(S, e);
            i++;
        }
        else if(b=='E')
        {
            E();
        }
        else if(b=='T')
        {
            T();
        }
        else if(b=='G')
        {
            G();
        }
        else if(b=='S')
        {
            S1();
        }
        else if(b=='F')
        {
            F();
        }
        else
        {
            cout<<"error!"<<endl;
            exit(0);
        }
    }
    cout<<"acc!"<<endl;
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值