表示式語法分析——遞迴子程式法
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;
}