C++:基于LL(1)方法的语法分析程序-1
2015-12-05 16:08
549 查看
1、实验目的
设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。
2、实验要求
(1) 根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:
a.直接输入根据已知文法构造的分析表M;
b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;
c.输入已知文法,由程序自动构造文法的分析表M。
(2) 程序具有通用性
所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。
(3) 有运行实例
对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。
(4) 提交实验报告,报告内容参考“词法分析程序”
以上为要求,当然,这么庞大的要求我们要慢慢来,慢慢来。
我们先完成给定一个固定的文法的预测分析表,然后判断一个符号串是否属于该文法。我们的思路是这样的
不断判断分析栈的栈顶和剩余串的头是否一样
如果不同,则根据文法的预测分析表对分析栈栈顶进行推导
发生匹配后符号串减去头,栈弹出栈顶
当然为了流畅实现上述三个重复的活动,需要一些函数的辅助。以下为我的代码,如有谬误,望指出
因为机房里是VS2010所以注释是英文的,最后的代码会变成中文的注释。我们大概的分析过程出来了,那么下一步,我们从一个限定了格式的txt文件里面读出我们需要的预测分析表。
设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。
2、实验要求
(1) 根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:
a.直接输入根据已知文法构造的分析表M;
b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;
c.输入已知文法,由程序自动构造文法的分析表M。
(2) 程序具有通用性
所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。
(3) 有运行实例
对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。
(4) 提交实验报告,报告内容参考“词法分析程序”
以上为要求,当然,这么庞大的要求我们要慢慢来,慢慢来。
我们先完成给定一个固定的文法的预测分析表,然后判断一个符号串是否属于该文法。我们的思路是这样的
不断判断分析栈的栈顶和剩余串的头是否一样
如果不同,则根据文法的预测分析表对分析栈栈顶进行推导
发生匹配后符号串减去头,栈弹出栈顶
当然为了流畅实现上述三个重复的活动,需要一些函数的辅助。以下为我的代码,如有谬误,望指出
#include <iostream> #include <string> #include<stack> using namespace std; string E[6]={"TE'","","","TE'","",""}; string E1[6]={"","+TE'","","","ε","ε"}; string T[6]={"FT'","","","FT'","",""}; string T1[6]={"","ε","*FT'","","ε","ε"}; string F[6]={"i","","","(E)","",""}; bool invertStack(stack<string> &one_stack) { if (one_stack.empty())//if the stack is null,then don't invert it { return false; }else { //init a stack to save the inverted stack stack<string> invert; while(!one_stack.empty()) { invert.push(one_stack.top()); one_stack.pop(); } //this moment the stack's inverted state is the stack invert ,so get it back one_stack=invert; return true; } } void displayStack(stack<string> one_stack) { invertStack(one_stack); while(!one_stack.empty()) { cout<<one_stack.top(); one_stack.pop(); } cout<<" "; } string configureProduction(stack<string> const &analyse,int char_index) { if (analyse.top()=="E") { if (E[char_index]!="") { return E[char_index]; } }else if (analyse.top()=="E'") { if (E1[char_index]!="") { return E1[char_index]; } }else if (analyse.top()=="T") { if (T[char_index]!="") { return T[char_index]; } }else if (analyse.top()=="T'") { if (T1[char_index]!="") { return T1[char_index]; } }else if (analyse.top()=="F") { if (F[char_index]!="") { return F[char_index]; } } return "error"; } bool isMatching(stack<string> const &analyse,char odd_first_char) { if (analyse.top()[0]==odd_first_char) { return true; } return false; } int findTIndex(char some)//to find the Terminated char's index { switch (some) { case 'i':return 0; case '+':return 1; case '*':return 2; case '(':return 3; case ')':return 4; case '#':return 5; default: cout<<"error"; return -1; } } bool display(stack<string> &analyse,string &odd) { static int step=1; if (step==1)//while the first step is clearly { cout<<step<<" "; displayStack(analyse); cout<<odd<<" "; int char_index=findTIndex(odd[0]); if (char_index==-1) { return false; } string production=configureProduction(analyse,char_index); cout<<analyse.top()<<"->"<<production<<endl; if (production=="error") { return false; } step++; analyse.pop();//pop the top element while(production.size()!=1) { if (production[production.length()-1]=='\'') { string temp=production.substr(production.length()-2,production.length()-1); analyse.push(temp); production=production.substr(0,production.length()-2); }else { string temp=production.substr(production.length()-1,production.length()-1); analyse.push(temp); production=production.substr(0,production.length()-1); } } analyse.push(production); } else { if (isMatching(analyse,odd[0])) { cout<<step<<" "; displayStack(analyse); cout<<odd<<" "; if (odd[0]=='#') { cout<<"接受"<<endl; return false; } cout<<"“"<<odd[0]<<"”匹配"<<endl; odd=odd.substr(1,odd.length()-1);//if match odd string decrease analyse.pop(); step++; return true; }else { cout<<step<<" "; displayStack(analyse); cout<<odd<<" "; int char_index=findTIndex(odd[0]); if (char_index == -1) { return false; } string production=configureProduction(analyse,char_index); cout<<analyse.top()<<"->"<<production<<endl; if (production=="error") { return false; } step++; if (production=="ε") { analyse.pop(); return true; } analyse.pop();//pop the top element while(production.size()!=1) { if (production[production.length()-1]=='\'') { string temp=production.substr(production.length()-2,production.length()-1); analyse.push(temp); production=production.substr(0,production.length()-2); }else { string temp=production.substr(production.length()-1,production.length()-1); analyse.push(temp); production=production.substr(0,production.length()-1); } } analyse.push(production); } } } int main() { cout<<"请输入符号串"; string inputstring; cin>>inputstring; //init a stack to analyse stack<string> analyse_s; analyse_s.push("#"); analyse_s.push("E"); //init a odd string string odd =inputstring; cout<<"步骤 "<<"分析栈 "<<"剩余输入串 "<<"推导所用产生式或匹配"<<endl; //the first step is succeed while(!odd.empty()&&display(analyse_s,odd)); system("pause"); return 0; }
因为机房里是VS2010所以注释是英文的,最后的代码会变成中文的注释。我们大概的分析过程出来了,那么下一步,我们从一个限定了格式的txt文件里面读出我们需要的预测分析表。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- 探讨C语言的那些小秘密之断言
- C语言实现BMP转换JPG的方法
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- C语言查找数组里数字重复次数的方法
- C语言泛型编程实例教程