1. 程式人生 > >表示式語法分析——遞迴子程式法

表示式語法分析——遞迴子程式法

Problem Description

遞迴子程式法是一種確定的自頂向下語法分析方法,要求文法是LL(1)文法。它的實現思想是對應文法中每個非終結符編寫一個遞迴過程,每個過程的功能是識別由該非終結符推出的串,當某非終結符的產生式有多個候選式時能夠按LL(1)形式唯一地確定選擇某個候選式進行推導。請根據下面的表示式LL(1)文法,構造遞迴子程式,完成對錶達式的語法分析。

表示式文法如下:

    E→TG

    G→+TG | ε

    T→FS

    S→*FS | ε

    F→(E) | i


對於給定的輸入串(長度不超過50個符號),請輸出分析過程中用到的所有產生式,並指明該輸入串是否為該文法能生成的表示式,輸出共11行,前10行每行兩個資料用空格隔開,表示推導時所用產生式順序號(從0開始),最後一行是accept,表示i+i*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


[email protected]不是文法能生成的表示式,輸出共5行,前5行每行兩個資料用空格隔開,表示推導時所用產生式序號(從0開始),最後一行是error,表示[email protected]不是文法能生成的表示式。@不是合法的文法符號,輸出格式舉例:

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

Input

輸入資料只有一行,代表待分析的符號串,以#號結束

Output

輸出推導過程中所有的產生式,按照使用順序給出。輸出詳細說明見題目描述中的例子。

Sample Input

i+i*i#

Sample Output

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

code:

#include <cstdio>
#include <cstdlib>

using namespace std;

char str[100];
int h = 0;
int i = 0;

void funE();
void funG();
void funT();
void funS();
void funF();

void funE()
{
    printf("%d E-->TG\n", i++);
    funT();
    funG();
}

void funG()
{
    if(str[h] == '+')
    {
        printf("%d G-->+TG\n", i++);
        h++;
        funT();
        funG();
    }
    else
    {
        printf("%d G-->&\n", i++);
    }
}

void funT()
{
    printf("%d T-->FS\n", i++);
    funF();
    funS();
}

void funS()
{
    if(str[h] == '*')
    {
        printf("%d S-->*FS\n", i++);
        h++;
        funF();
        funS();
    }
    else
    {
        printf("%d S-->&\n", i++);
    }
}

void funF()
{
    if(str[h] == 'i')
    {
        printf("%d F-->i\n", i++);
        h++;
    }
    else if(str[h] == '(')
    {
        printf("%d F-->(E)\n", i++);
        h++;
        funE();
        if(str[h] == ')')
        {
            h++;
        }
        else
        {
            printf("error\n");
            exit(0);
        }
    }
    else
    {
        printf("error\n");
        exit(0);
    }
}

int main()
{
    scanf("%s", str);
    funE();
    if(str[h]!='#')
    {
        printf("error\n");
    }
    else
    {
        printf("accept\n");
    }
    return 0;
}