文法变换
G(E):
E→Eω0T|T E为算术表达式,T为项
T→Tω1F|F F为因式项,ω0为 +或 -, ω1为 * 或 /
F→i|(E) i 为变量或常量
G(E)不是LL(1)文法,所以需要进行文法变换
G’(E):
E→T{ω0T}
T→F{ω1F}
F→i|(E)
或者G”(E):
E→TA
A→{ω0T}A
T→FB
B→{ω1F}B
F→i|(E)
递归下降法
Preset.h
#ifndef PRESET_H_INCLUDED
#define PRESET_H_INCLUDED
std::string Str;
int top;
void HandleE();
void HandleA();
void HandleT();
void HandleB();
void HandleF();
#endif // PRESET_H_INCLUDED
main.c
#include <iostream>
#include <cstdio>
#include <cstring>
#include "Preset.h"
using namespace std;
int main()
{
while(cin >> Str)
{
top=0;
if(Str[top]=='#')
cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
void HandleE()
{
HandleT();
HandleA();
}
void HandleA()
{
if(Str[top]=='+' || Str[top]=='-')
{
top++;
HandleT();
HandleA();
}
}
void HandleT()
{
HandleF();
HandleB();
}
void HandleB()
{
if(Str[top]=='*' || Str[top]=='/')
{
top++;
HandleF();
HandleB();
}
}
void HandleF()
{
if(isalpha(Str[top]))
top++;
else if(Str[top]=='(')
{
top++;
HandleE();
if(Str[top]==')')
top++;
}
}
LL(1)
LL(1)分析表如下:
栈顶符/当前符 | i | + | * | ( | ) | # |
---|---|---|---|---|---|---|
E | 1 | 1 | ||||
A | 2 | 3 | 3 | |||
T | 4 | 4 | ||||
B | 3 | 5 | 3 | 3 | ||
F | 6 | 7 | ||||
) | 6 | |||||
# | OK |
其中
- (AT,P)
- (AT,N)
- (空,P)
- (BF,P)
- (BF,N)
- (空,N)
- ( )E,N)
P表示不变,N表示读取下一个
故
AT ——1、2
BF——4、5
空——3、6
)E——7
P——1、3、4
N——2、5、6、7
Preset.h
#ifndef PRESET_H_INCLUDED
#define PRESET_H_INCLUDED
std::string Str;
int top;//栈顶符指针
int stop;//当前符指针
int tell();
std::string Stack_ch;
#endif // PRESET_H_INCLUDED
main.c
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include "Preset.h"
using namespace std;
int main()
{
while(cin >> Str)
{
top=0;
stop=0;
Stack_ch[top]='#';
Stack_ch[++top]='E';
int ans=0;
ans=tell();
while(ans!=-1 && ans!=0)
{
ans=tell();
}
if(ans==-1)cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
int tell()
{
int op=-1;
if(Stack_ch[top]=='#' && Str[stop]=='#')
{
return op;
}
op=0;
switch(Stack_ch[top])
{
case 'E':
if(Str[stop]=='(' || isalpha(Str[stop]))op=1;
break;
case 'A':
if(Str[stop]=='+' || Str[stop]=='-')op=2;
else if(Str[stop]==')' || Str[stop]=='#')op=3;
break;
case 'T':
if(Str[stop]=='(' || isalpha(Str[stop]))op=4;
break;
case 'B':
if(Str[stop]=='+' || Str[stop]=='-' || Str[stop]==')' || Str[stop]=='#')op=3;
else if(Str[stop]=='*' || Str[stop]=='/')op=5;
break;
case 'F':
if(Str[stop]=='(')op=7;
else if(isalpha(Str[stop]))op=6;
break;
case ')':
if(Str[stop]==')')op=6;
break;
default:
break;
}
if(op==0)return op;
top--;
if(op==2 || op==5 || op==6 || op==7)stop++;
switch(op)
{
case 1:
case 2:
Stack_ch[++top]='A';
Stack_ch[++top]='T';
break;
break;
case 4:
case 5:
Stack_ch[++top]='B';
Stack_ch[++top]='F';
break;
case 7:
Stack_ch[++top]=')';
Stack_ch[++top]='E';
break;
default:
break;
}
return op;
}