求助大佬解决一个小问题

qq_35491782 2018-01-14 07:18:57
非LL(1)文法与LL(1)文法的转化,本人别处借鉴的代码,但是在VC6.0创建的c++ source file 中打开有错误,能有人指出那有问题吗?
#include<iostream>
#include <fstream>
#include<string>
#include<list>
using namespace std;

list<string> vf;
list<list<string>> ListVf;

list<list<string>>::iterator it_i;
list<list<string>>::iterator it_j;
list<string>::iterator it_k;
list<string>::iterator it_m;

char ch;//每个要比对的字符
string str = "";//每个要分析的单词
ifstream in;//文件输入流
char buf[1024]; //缓存
char *p;//指针,之所以用指针,是因为有回退的操作

//加载文件,并读到缓存
void infile(string filename){
p = buf;
memset(buf, 0, 1024);
in.open(filename);
while ((*p = in.get()) != EOF)
{
p++;
}
p = buf;//将指针移到缓存的首地址
}
//关闭文件
void closefile(){
in.close();
}

//获取缓存中当前指针所指字符,根据返回值判断是否到缓存结束,即文件结束(缓存要足够大)
int Getchar(){
if (*p != EOF){
ch = *p;
p++;
return 1;
}
else
return 0;
}
//若当前字符为空,或者为制表符(9)或者为换行符(10)或者为换页符(12)则取下一个字符,直到当前字符合法
void getBC(){
while (ch == ' ' || ch == 9 || ch == 10 || ch == 12)
Getchar();
}
//连接字符串
void Concat(){
str += ch;
}
//判断当前字符是否为|
bool isVerticalBar(){
return ch =='|';
}
//判断当前字符是否为;
bool isSemicolon(){
return ch == ';';
}
//代码异常出现
void procError(){
cout << "Something is wrong..." << endl;
}

//扫描得到文法的列表
int scan(){
if (!Getchar()) return 0;
getBC();
if (ListVf.empty()){
ListVf.push_back(vf);
//cout << "sizeof(listvf):" << ListVf.size() << endl;
}
if (ch == '-'){
ListVf.back().push_back(str);
str = "";
//cout << "插入成功么:" << ListVf.back().back()<<endl;
Getchar();
return 1;
}
else if (isSemicolon()){
ListVf.back().push_back(str);
//(ListVn.back()->data).insertAsLast(str);
str = "";
//cout << "插入成功么:" << ListVf.back().back() << endl;
ListVf.push_back(*new list<string>);
//cout << "新添加一个List" << endl;

}
else if (isVerticalBar()){
ListVf.back().push_back(str);
//ListVn.last()->data.insertAsLast(str);
//cout << "插入成功么:" << ListVf.back().back();
//cout << endl << "sizeof(listvn):"<<ListVf.size() << endl;
str = "";
}
else{
Concat();
//cout << str << endl;
}
return 1;
}
void show(){//显示文法
for (it_i = ListVf.begin(); it_i != ListVf.end(); ++it_i){
list<string>::iterator j = it_i->begin();
cout << *j << "->";
for (int i = 2; i < it_i->size();i++){
j++;
cout << *j << " | ";
}
j++;
cout << *j;
cout << ";"<<endl<<endl;
}
}

//消除左递归
int removeLeftRecursion(){

while (scan());
ListVf.pop_back();
cout << "----------------" << endl;
cout << "初始的文法:" << endl;
show();//显示初始文法
cout << "----------------" << endl;


list<string> vn;//非终结符集合
list<list<string>>::iterator it;
for (it = ListVf.begin(); it != ListVf.end(); ++it){//非终结符集合
vn.push_back(it->front());
}

list<string>::iterator it_vn;
cout << "非终结符集合" << endl;
for (it_vn = vn.begin(); it_vn != vn.end(); ++it_vn){
cout << *it_vn << " ";
}
cout << endl<<"----------------" << endl;
int i = 0;
for (it_i = ListVf.begin(); it_i != ListVf.end(); ++it_i){
for (it_j = ListVf.begin(); it_j != it_i; ++it_j){
it_k = it_i->begin();
for (it_k++; it_k != it_i->end();){
string str1 = *it_k;
string str2 = it_j->front();

if (str1.substr(0,1)==str2){//若Pi = pja
it_m = it_j->begin();
for (it_m++; it_m != it_j->end(); it_m++){
it_i->insert(it_k,*it_m+str1.substr(1,str1.length()));
}
it_k = it_i->erase(it_k);
for (int i = 0; i < it_j->size() - 1;i++){
it_k--;
}
}
else{
++it_k;
}
}
}
bool flag = false;
list<string>::iterator i = it_i->begin();
string str2 = "";
string str3 = "";
for (i++; i != it_i->end();++i){
if (i->substr(0,1) == it_i->front()){//扫描判断是否存在R->Ra...的情况
string s = i->substr(1, i->size());
*i = s;
str2 = s;
flag = true; break;
}
}
it_i->unique();//去重
if (flag){//若存在直接左递归,则消除之
list<string>::iterator j = it_i->begin();
str3 = it_i->front() + "'";//记录R'
for (j++; j != it_i->end(); j++){
*j = *j + it_i->front() + "'";
}
list<string> la;//添加R'生成式到文法
la.push_back(str3);
la.push_back(str2+str3);
la.push_back("@");
ListVf.push_back(la);
}
}
cout << "消除左递归后的文法:" << endl;
show();//显示消除左递归后的数值
cout << "----------------" << endl;
return 0;
}
int removeLeftGene(){

for (it_i = ListVf.begin(); it_i != ListVf.end(); ++it_i){
list<string>::iterator i = it_i->begin();
list<string>::iterator p = it_i->begin();
i++;
list<string> lm;
for (; i != it_i->end(); i++){
p = i;
if (i->at(0) > 'z' || i->at(0) < 'a')continue;
for (p++; p != it_i->end(); p++){
if (p->at(0) == i->at(0)){
if (p->at(p->size() - 1) >= 'a'&&p->at(p->size() - 1) <= 'z') {//末位是小写字母
if (lm.empty()){

if (i->size() > 1){
lm.push_back(i->substr(1, i->size() + 1));
}
if (p->size() > 1){
lm.push_back(p->substr(1, i->size() + 1));
}
lm.push_back("@");
lm.push_back(it_i->front()+"^");//没搞懂只能从后面pushS^
}else
lm.push_back(*p);
i = it_i->erase(i);
*i = i->substr(0, 1) + it_i->front() + "^";
}
else{ continue; }
}
else{ continue; }
}
if (!lm.empty()){
string s = lm.back();
lm.pop_back();
lm.push_front(s);
ListVf.push_back(lm);
}
}
}
cout << "提取左因子后的文法:" << endl;
show();//显示提取昨因子后的文法
cout << "----------------" << endl;
return 0;
}
int main(){
string filename = "./test.txt";
infile(filename);
removeLeftRecursion();
removeLeftGene();
closefile();
return 0;
}
...全文
646 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
heronism 2018-01-15
  • 打赏
  • 举报
回复
你应该先把你所谓的错误贴出来
赵4老师 2018-01-15
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
赵4老师 2018-01-15
  • 打赏
  • 举报
回复
LEX+YACC FLEX+BISON
大风哉 2018-01-15
  • 打赏
  • 举报
回复
引用 2 楼 heronism 的回复:
你应该先把你所谓的错误贴出来
这么长而又不能把问题点清晰地点出来的帖子应该不太有人愿意回答的。

64,636

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧