实现 LL(1)分析中控制程序( 表驱动程序),根据给定赋值语句的 LL(1)文法,完成分析过程。
输入:词法分析的二元式序列,输入结构如下:
typedef struct Dual
{
int Identifier;
char Character;
}
输出:输入串是否为该文法定义的算术表达式(bool)。
G[S]: S→V=E
E→TE′
E′→ ATE′|ε
T→FT′
T′→ MFT′|ε
F→ (E)|i
A→+|-
M→*|/
V→i
(1) 递归下降分析程序应能发现简单的语法错误。
语言:C++语言
编辑器:codeblocks
txt文件:用于保存词法分析结果,并作为语法分析的输入。
字符类型及字符串类型的识别使用穷举法搜索法。穷举搜索法是按某种顺序对所有可能的值进行逐个验证,从中找出符合条件的解。此方需要多重循环,简单易行,并且适合词法分析程序的查表原则。
正则文法的分析使用穷举搜索法及回溯法。穷举回溯法与以上同理,即对规则进行逐一的验证。回溯法主要用于/* */标记的注释的回溯,当无法匹配*/时,需要进行回溯,从/*标记的后一位重新开始进行扫描分析。
在程序中,由于没有编写产生FIRST集和FOLLOW集的函数,因此需要对文法进行预处理,得到其FIRST集和FOLLOW集,本程序的FIRST集和FOLLOW集如下:
元素 |
FIRST集 |
FOLLOW集 |
S→V=E |
i, |
# |
E→TE′ |
(,i |
),# |
E′→ ATE′|ε |
ε,+,- |
),# |
T→FT′ |
(,i |
+,-,),# |
T′→ MFT′|ε |
*,/,ε |
+,-,),# |
F→ (E)|i |
(,i |
*,/,+,-,),# |
A→+|- |
+,- |
(,i |
M→*|/ |
*,/ |
(,i |
V→i |
i |
= |
函数原型:int main()
参数:无
返回值:0(default)
功能说明:程序的入口,首先调用读文件程序读入文件,然后调用语法分析入口程序开始语法分析,若语法分析正确,最终输出结果将由主函数输出,否则将在中间环节返回错误信息。
函数原型:bool ReadFile()
参数:无
返回值:是否正确读取文件内容
功能说明:将文件内容读入,并放入指定的数据结构中
函数原型:void advance()
参数:无
返回值:无
功能说明:移动游标
函数原型:bool S();
bool E();
bool E1();
bool T();
bool T1();
bool F();
bool A();
bool M();
bool V();
参数:无
返回值:符合文法规则返回true,否则返回false
功能说明:分别定义各语句的文法规则,通过互相调用实现递归算法。
函数原型:void error_report(string Wrong)
参数:错误位置信息
返回值:无
功能说明:若产生输入串与语法规则不符,则将被其他函数调用以输出错误信息
int main()
{
if(ReadFile())
{
cout << "file input:";
for(current = listdual.begin(); current != listdual.end(); ++current)
{
cout << (*current).Character <<" " ;
}
cout <<"\n";
current = listdual.begin();
cout << "analysis:" << endl;
//从起始符号开始,自顶向下分析
if(S())
cout << "The result is Right!" << endl;
else
error_report("input");
}
else
{
error_report("ReadFile()");
}
return 0;
}
图1 main函数调用逻辑关系图
bool ReadFile()
{
DUAL temp;
inFile.open("right.txt");
while(!inFile.eof())
{
inFile >> temp.Identifier >> temp.Character;
listdual.push_back(temp);
}
inFile.close();
return true;
}
void advance()
{
current++;
}
void error_report(string Wrong)
{
cout <<"ERROR:"<< Wrong << " error"<< endl;
}
// S->V=E
bool S()
{
if(current == listdual.end())
{
error_report("S() read file");
return false;
}
cout<<"S->V=E"< if(!V()) return false; if((*current).Character == '='){ cout<<"="< advance(); }else return false; if(!E()) return false; return true; } //E→TE′ bool E(){ if(current == listdual.end()) { error_report("E() read file"); return false; } cout<<"E->TE'"< if(!T()) return false; if(!E1()) return false; return true; } // E′→ ATE′|ε bool E1(){ if(current == listdual.end()) { error_report("E1() read file"); return false; } else { if((*current).Character == '+' || (*current).Character == '-' ) { cout<<"E'→ATE'"< //按照匹配的候选式进行递归。 if(!A()) return false; if(!T()) return false; if(!E1()) return false; } else if((*current).Character == ')' || (*current).Character == '#') cout<<"E'→ε"< else { error_report("E1()"); return false; } } return true; } // T→FT′ bool T(){ if(current == listdual.end()) { error_report("T() read file"); return false; } cout<<"T→FT′"< if(!F()) return false; if(!T1()) return false; return true; } //T′→ MFT′|ε bool T1(){ if(current == listdual.end()) { error_report("E1() read file"); return false; } else { if((*current).Character == '*' || (*current).Character == '/' ) { cout<<"T′→ MFT′"< //按照匹配的候选式进行递归。 if(!M()) return false; if(!F()) return false; if(!T1()) return false; } else if((*current).Character == ')' || (*current).Character == '#'||(*current).Character == '+'||(*current).Character == '-') cout<<"T'→ε"< else { error_report("E1()"); return false; } } return true; } // F→ (E)|i bool F() { if(current == listdual.end()) { error_report("F() read file"); return false; } if((*current).Character == '(') { advance(); if(!E()) return false; else if((*current).Character == ')') { advance(); cout << "F->(E)" < } else return false; } if((*current).Character == 'i') { cout << "F->i" << endl; advance(); } return true; } // A→+|- bool A() { if(current == listdual.end()) { error_report("A() read file"); return false; } if((*current).Character == '+'||(*current).Character == '-') { cout<<"A→"<< (*current).Character < } else { error_report("A()"); return false; } advance(); return true; } // M→*|/ bool M() { if(current == listdual.end()) { error_report("M() read file"); return false; } if((*current).Character == '*' || (*current).Character == '/') { cout << "M->" << (*current).Character << endl; advance(); } else { error_report("M()"); return false; } return true; } // V→i bool V(){ if(current == listdual.end()) { error_report("V() read file"); return false; } if((*current).Character == 'i'){ cout << "V->" << (*current).Character << endl; advance(); } else{ error_report("V()"); return false; } return true; } 1 i 2 = 3 ( 4 i 5 + 6 i 7 ) 8 / 9 i 10 # 测试结果: 1 i 2 + 3 i 4 ( 3 i 4 #
测试用例二:错误输入串