大家帮忙看看这个词法分析程序,运行后有错误 ( 积分: 33 )

  • 主题发起人 主题发起人 hyzb
  • 开始时间 开始时间
H

hyzb

Unregistered / Unconfirmed
GUEST, unregistred user!
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
using namespace std;
// 保留字数组定义
char* ReserveWords[35] = {
"and", "array", "begin
", "case", "const", "div", "do", "downto", "else
", "end", "file",
"for", "function", "goto", "if", "in", "label", "mod", "nil", "not", "of", "or", "packed",
"procedure", "program", "record", "repeat", "set", "then
", "to", "type", "until", "var",
"while", "with"
};
char arrow[] = " -----> ";
char enter[] = "/r/n";
// 读入ch
char GetChar(ifstream&amp;
src)
{
char cRet;
src.get(cRet);
return cRet;
}
// 读入空格
char GetBC(ifstream&amp;
src)
{
char cRet;
src.get(cRet);
while (cRet == ' ')
src.get(cRet);
return cRet;
}
// 连接单词符号
void Concat(char *str, char c)
{
size_t n = strlen(str);
str[n++] = c;
str[n] = '/0';
}
// 判断是否为保留字
bool Reserve(const char* str)
{
bool bRet = false;
for (int i = 0;
i < 35;
i++)
{
if (_stricmp(ReserveWords, str) == 0)
{
bRet = true;
break;
}
}
return bRet;
}
// 回调字符
char Retract(ifstream&amp;
src)
{
src.seekg(-1, ios::cur);
return '/0';
}
// 分析函数
void Analyzer(ifstream&amp;
src, ofstream&amp;
dst)
{
char ch;
char strToken[1024] = "";
ch = GetBC(src);
// 判断标识符的情况
if (isalpha(ch))
{
while (isalpha(ch) || isdigit(ch) || ch == '_')
{
Concat(strToken, ch);
ch = GetChar(src);
}
ch = Retract(src);
if (Reserve(strToken))
dst << strToken << arrow << "Reserve Word" << enter;
else
dst << strToken << arrow << "Identifier" << enter;
}
// 判断数值的情况
else
if (isdigit(ch))
{
while (isdigit(ch))
{
Concat(strToken, ch);
ch = GetChar(src);
}
Retract(src);
dst << strToken << arrow << "Number" << enter;
}
// 判断字符串的情况
else
if (ch == '/'')
{
Concat(strToken, ch);
ch = GetChar(src);
while (ch != '/'')
{
Concat(strToken, ch);
ch = GetChar(src);
}
if (ch != '/'')
cerr << "String is too long - more than 1024 bytes!" << endl;
else
{
Concat(strToken, ch);
dst << strToken << arrow << "String" << enter;
}
}
// 过滤注释
else
if (ch == '{')
{
while (GetChar(src) != '}')

}
// 判断所有没有歧义的单目运算符
else
if (ch == '+')
dst << ch << arrow << "Plus" << enter;
else
if (ch == '-')
dst << ch << arrow << "Minus" << enter;
else
if (ch == '*')
dst << ch << arrow << "Multiply" << enter;
else
if (ch == '/')
dst << ch << arrow << "Divide" << enter;
else
if (ch == '=')
dst << ch << arrow << "Equal" << enter;
else
if (ch == '[')
dst << ch << arrow << "Left Square Brackets" << enter;
else
if (ch == ']')
dst << ch << arrow << "Right Square Brackets" << enter;
else
if (ch == ',')
dst << ch << arrow << "Comma" << enter;
else
if (ch == '^')
dst << ch << arrow << "Pointer" << enter;
else
if (ch == ';')
dst << ch << arrow << "Semicolon" << enter;
else
if (ch == '(')
dst << ch << arrow << "Left Parenthesis" << enter;
else
if (ch == ')')
dst << ch << arrow << "Right Parenthesis" << enter;
// 判断<、<>和<=
else
if (ch == '<')
{
ch = GetChar(src);
if (ch == '>')
dst << "<>" << arrow << "Unequal" << enter;
else
if (ch == '=')
dst << "<=" << arrow << "Less or Equal" << enter;
else
{
dst << '<' << arrow << "Less" << enter;
Retract(src);
}
}
// 判断>和>=
else
if (ch == '>')
{
ch = GetChar(src);
if (ch == '=')
dst << ">=" << arrow << "Greater or Equal" << enter;
else
{
dst << '>' << arrow << "Greater" << enter;
Retract(src);
}
}
// 判断.和..
else
if (ch == '.')
{
ch = GetChar(src);
if (ch == '.')
dst << ".." << arrow << "Bound" << enter;
else
{
dst << '.' << arrow << "Point" << enter;
Retract(src);
}
}
// 判断:和:=
else
if (ch == ':')
{
ch = GetChar(src);
if (ch == '=')
dst << ":=" << arrow << "Assign" << enter;
else
{
dst << ':' << arrow << "Colon" << enter;
Retract(src);
}
}
}
int main(int argc, char* argv[])
{
string strSrc;
// 命令行的支持
if (argc == 1)
{
cout << "Please input PASCAL source file name: ";
getline(cin, strSrc);
}
else
strSrc = argv[1];
// 打开文件
ifstream src(strSrc.c_str());
if (src.fail())
{
cerr << "/aFailed openning /"" << strSrc << "/"!" << endl;
return 1;
}
ofstream dst("Result.txt");
// 开始解析
while (!src.eof())
Analyzer(src, dst);
// 收尾工作
dst.close();
src.close();
cout << "The result of Analyzing is written into Result.txt." << endl;
return 0;
}
我先在c盘新建了一个测试的txt文件,运行后我输入了文件路径c:\test.txt之后回车,程序就报错说有一段内存不能被写入,程序就异常中断了,可是却能生成了分析结果的result.txt文件。
之后我把 // 开始解析while (!src.eof()) Analyzer(src, dst); 这一段改成了:
doAnalyzer(src, dst); while(!src.eof());程序就可以正常结束了,但是生成的分析结果却不全,只能分析第一个单词,后面的语句都没法分析。
高手帮忙看看 
 
#include <iostream>
#include <fstream>
#include <string>
#include <string.h>
#include <ctype.h>
using namespace std;
// 保留字数组定义
char* ReserveWords[35] = {
"and", "array", "begin
", "case", "const", "div", "do", "downto", "else
", "end", "file",
"for", "function", "goto", "if", "in", "label", "mod", "nil", "not", "of", "or", "packed",
"procedure", "program", "record", "repeat", "set", "then
", "to", "type", "until", "var",
"while", "with"
};
char arrow[] = " -----> ";
char enter[] = "/r/n";
// 读入ch
char GetChar(ifstream&amp;
src)
{
char cRet;
src.get(cRet);
return cRet;
}
// 读入空格
char GetBC(ifstream&amp;
src)
{
char cRet;
src.get(cRet);
while (cRet == ' ')
src.get(cRet);
return cRet;
}
// 连接单词符号
void Concat(char *str, char c)
{
size_t n = strlen(str);
str[n++] = c;
str[n] = '/0';
}
// 判断是否为保留字
bool Reserve(const char* str)
{
bool bRet = false;
for (int i = 0;
i < 35;
i++)
{
if (_stricmp(ReserveWords, str) == 0)
{
bRet = true;
break;
}
}
return bRet;
}
// 回调字符
char Retract(ifstream&amp;
src)
{
src.seekg(-1, ios::cur);
return '/0';
}
// 分析函数
void Analyzer(ifstream&amp;
src, ofstream&amp;
dst)
{
char ch;
char strToken[1024] = "";
ch = GetBC(src);
// 判断标识符的情况
if (isalpha(ch))
{
while (isalpha(ch) || isdigit(ch) || ch == '_')
{
Concat(strToken, ch);
ch = GetChar(src);
}
ch = Retract(src);
if (Reserve(strToken))
dst << strToken << arrow << "Reserve Word" << enter;
else
dst << strToken << arrow << "Identifier" << enter;
}
// 判断数值的情况
else
if (isdigit(ch))
{
while (isdigit(ch))
{
Concat(strToken, ch);
ch = GetChar(src);
}
Retract(src);
dst << strToken << arrow << "Number" << enter;
}
// 判断字符串的情况
else
if (ch == '/'')
{
Concat(strToken, ch);
ch = GetChar(src);
while (ch != '/'')
{
Concat(strToken, ch);
ch = GetChar(src);
}
if (ch != '/'')
cerr << "String is too long - more than 1024 bytes!" << endl;
else
{
Concat(strToken, ch);
dst << strToken << arrow << "String" << enter;
}
}
// 过滤注释
else
if (ch == '{')
{
while (GetChar(src) != '}')

}
// 判断所有没有歧义的单目运算符
else
if (ch == '+')
dst << ch << arrow << "Plus" << enter;
else
if (ch == '-')
dst << ch << arrow << "Minus" << enter;
else
if (ch == '*')
dst << ch << arrow << "Multiply" << enter;
else
if (ch == '/')
dst << ch << arrow << "Divide" << enter;
else
if (ch == '=')
dst << ch << arrow << "Equal" << enter;
else
if (ch == '[')
dst << ch << arrow << "Left Square Brackets" << enter;
else
if (ch == ']')
dst << ch << arrow << "Right Square Brackets" << enter;
else
if (ch == ',')
dst << ch << arrow << "Comma" << enter;
else
if (ch == '^')
dst << ch << arrow << "Pointer" << enter;
else
if (ch == ';')
dst << ch << arrow << "Semicolon" << enter;
else
if (ch == '(')
dst << ch << arrow << "Left Parenthesis" << enter;
else
if (ch == ')')
dst << ch << arrow << "Right Parenthesis" << enter;
// 判断<、<>和<=
else
if (ch == '<')
{
ch = GetChar(src);
if (ch == '>')
dst << "<>" << arrow << "Unequal" << enter;
else
if (ch == '=')
dst << "<=" << arrow << "Less or Equal" << enter;
else
{
dst << '<' << arrow << "Less" << enter;
Retract(src);
}
}
// 判断>和>=
else
if (ch == '>')
{
ch = GetChar(src);
if (ch == '=')
dst << ">=" << arrow << "Greater or Equal" << enter;
else
{
dst << '>' << arrow << "Greater" << enter;
Retract(src);
}
}
// 判断.和..
else
if (ch == '.')
{
ch = GetChar(src);
if (ch == '.')
dst << ".." << arrow << "Bound" << enter;
else
{
dst << '.' << arrow << "Point" << enter;
Retract(src);
}
}
// 判断:和:=
else
if (ch == ':')
{
ch = GetChar(src);
if (ch == '=')
dst << ":=" << arrow << "Assign" << enter;
else
{
dst << ':' << arrow << "Colon" << enter;
Retract(src);
}
}
}
int main(int argc, char* argv[])
{
string strSrc;
// 命令行的支持
if (argc == 1)
{
cout << "Please input PASCAL source file name: ";
getline(cin, strSrc);
}
else
strSrc = argv[1];
// 打开文件
ifstream src(strSrc.c_str());
if (src.fail())
{
cerr << "/aFailed openning /"" << strSrc << "/"!" << endl;
return 1;
}
ofstream dst("Result.txt");
// 开始解析
while (!src.eof())
Analyzer(src, dst);
// 收尾工作
dst.close();
src.close();
cout << "The result of Analyzing is written into Result.txt." << endl;
return 0;
}
我先在c盘新建了一个测试的txt文件,运行后我输入了文件路径c:\test.txt之后回车,程序就报错说有一段内存不能被写入,程序就异常中断了,可是却能生成了分析结果的result.txt文件。
之后我把 // 开始解析while (!src.eof()) Analyzer(src, dst); 这一段改成了:
doAnalyzer(src, dst); while(!src.eof());程序就可以正常结束了,但是生成的分析结果却不全,只能分析第一个单词,后面的语句都没法分析。
高手帮忙看看 
 
不是不帮你看,长了点....
 
不是不帮你看,长了点..
建议你F7单步执行看一下
 
大家帮忙运行一下啊
 
这个词法分析程序还不完善,对变量的分析不完整,对于“2a”这个以数字开头的标志符无法判断为错误。谁能帮助改改啊
 
接受答案了.
 
后退
顶部