0
点赞
收藏
分享

微信扫一扫

实验:实现C语言小子集程序的词法分析

实现C语言小子集程序的词法分析

(1)以表1的小语言(C语言小子集)为例实现词法分析
实验:实现C语言小子集程序的词法分析_#include
(2)设计单词属性值;设计表格(表示标识符表),单词符号及机内表示
(3)编码实现词法分析程序
(4)要求:
- 输入方式:文件(源文件)
- 输出方式:词法分析的结果(单词串)输出到屏幕上同时保存文件上(目标文件)。
(5)要求实现:

  • 对正确源程序的识别;
  • 对包含有注释//和/* */的源程序的识别;
  • 对包含错误标识符和错误数的源程序的识别并作相应的错误处理。
    (6)自己设计3-5个测试实例,要求覆盖上述功能。测试实例可参看(附录A)

附录A

实验:实现C语言小子集程序的词法分析_#include_02

实验:实现C语言小子集程序的词法分析_标识符_03

源代码

//词法生成器
#include<iostream>
#include<vector>
using namespace std;
#include<fstream>
#include<iomanip>
#include<map>
#include<string>
map<string, int>SYMBOL;
vector<string>VARIABLE;//保存标识符
vector<int>v;//处理行
const int num = 25500;//文本最多25500个字符
bool Flag = true;//注释
string FileName = "3.txt";
FILE *f_out = fopen("符号表.txt", "w");
FILE *f = fopen("标识符表.txt", "w");
void LoadSymbol()
{
int sum = 0, i = 0;
string s = "";
char temp[num];
ifstream f_in("C语言小子集定义表.txt");
f_in.getline(temp, num, 0);//一次性读入所有符号,保存到temp中
//cout << temp << endl;
while (temp[i] != '#')
{
while (temp[i] != ':')
s += temp[i], i++;
i++;
while (temp[i] != '\n')
sum = sum * 10 + (temp[i] - '0'), i++;
SYMBOL[s] = sum;
s = "", sum = 0;
i++;
}
/*map<string, int>::iterator it;
for (it = SYMBOL.begin();it != SYMBOL.end();it++)
{
cout << (*it).first << ":" << (*it).second << endl;
}*/
}
int Find(string s)//查询函数,如果查到存在此关键词便返回值,否则返回零,不包括常数以及标识符
{
map<string, int>::iterator it;
it = SYMBOL.find(s);
if (it != SYMBOL.end())
{
return SYMBOL[s];
}
else
return 0;
}
//预处理(去空格以及注释)- Tab无法处理
void PreDeal(string &s)
{
//处理注释
int index = 0;
if (s.find("//") != -1)
{
index = s.find("//");
s = s.substr(0, index);
cout << s << endl;
}
else if (s.find("/*") != -1)
{
index = s.find("/*");
if (s.find("*/") == -1)
{
Flag = false;
s = "";
}
else
{
index = s.find("*/");
s = s.substr(index + 2, s.size() - 1);
}
}
else if (s.find("*/") != -1 && Flag == false)
{
index = s.find("*/");
s = s.substr(index + 2, s.size() - 1);
Flag = true;
}

//处理空格
string temp = "";
for (int i = 0;i < s.size();)
{
while (s[i] == ' '&&s[i + 1] == ' ')
{
i++;
}
temp += s[i];
i++;
}
s = temp;
}
//处理单行语句
void Deal(string &s, int line)
{
//fputs("adsdsa", f_out);
PreDeal(s);
string temp = "";
for (int i = 0;i < s.size();)
{
if (s[i] == '>')
{
if (s[i + 1] == '=')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL[">="]);
fputs("->,", f_out);
i = i + 2;
}
else
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL[">"]);
fputs("->,", f_out);
i++;
}
}
else if (s[i] == '<')
{
if (s[i + 1] == '=')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["<="]);
fputs("->,", f_out);
i = i + 2;
}
else
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["<"]);
fputs("->,", f_out);
i++;
}
}
else if (s[i] == '=')
{
if (s[i + 1] == '=')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["=="]);
fputs("->,", f_out);
i = i + 2;
}
else
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["="]);
fputs("->,", f_out);
i++;
}
}
else if (s[i] == '!'&&s[i + 1] == '=')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["!="]);
fputs("->,", f_out);
i = i + 2;
}
else if (s[i] == '&'&&s[i + 1] == '&')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["&&"]);
fputs("->,", f_out);
i = i + 2;
}
else if (s[i] == '|'&&s[i + 1] == '|')
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL["||"]);
fputs("->,", f_out);
i = i + 2;
}
else if (Find(temp = s[i]))
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL[temp]);
fputs("->,", f_out);
i++;
}
else if (true)
{
temp = "";
while (s[i] != ' '&&s[i] != '\n'&&s[i] != ')'&&s[i] != ';'&&s[i] != '('&&s[i] != '{'&&s[i] != '}'&&s[i] != '['&&s[i] != ']'&&s[i] != ','&&s[i] != '+'&&s[i] != '-'&&s[i] != '*'&&s[i] != '/'&&s[i] != '%'&&s[i] != '>'&&s[i] != '<'&&s[i] != '='&&s[i] != '!'&&s[i] != '&')
{
temp += s[i];
i++;
if (i == s.size())break;
}
if (Find(temp))
{
fputs("<", f_out);
fprintf(f_out, "%d,", SYMBOL[temp]);
fputs("->,", f_out);
}
else if (temp != "")
{
if (temp[0] >= '0'&&temp[0] <= '9' && (temp[temp.size() - 1] >= 'a'&&temp[temp.size() - 1] <= 'z' || temp[temp.size() - 1] >= 'A'&&temp[temp.size() - 1] <= 'Z'))
{
fputs("LexicalError,", f_out);
v.push_back(line);
}
else if ((temp[0] >= 'a'&&temp[0] <= 'z' || temp[0] >= 'A'&&temp[0] <= 'Z'))
{
fputs("<", f_out);
fprintf(f_out, "%d,", 1);
fprintf(f_out, "%s>,", temp.c_str());
VARIABLE.push_back(temp.c_str());
}
else
{
int sum = 0;
while (s[i] != ' '&&s[i] != ';'&&s[i] != ')'&&s[i] != ';')
sum = sum * 10 + (s[i] - '0'), i++;
fputs("<", f_out);
fprintf(f_out, "%d,", 2);
fprintf(f_out, "%s>,", temp.c_str());
}
}
}
if (s[i] == ' ' || s[i] == '\n')
i++;
}
}
void LoadFile()//读入文本
{
string s = "";
int i = 0, line = 1;
char temp[num];
ifstream f_in(FileName);
f_in.getline(temp, num, 0);
while (temp[i] != '#')
{
while (temp[i] != '\n')
{
s += temp[i];
i++;
}
if (Flag == false)
{
if (s.find("*/") != -1)
Flag = true;
fputs("\n", f_out);
}
else
Deal(s, line);
fputs("\n", f_out);
s = "", i++, line++;
}
if (v.size() == 0)
fputs("LexicalError(s) 0 errors\n", f_out);
else
{
fputs("LexicalError(s) on line(s) ", f_out);
fprintf(f_out, "%d", v[0]);
for (int j = 1;j < v.size();j++)
fprintf(f_out, ",%d", v[j]);
fputs("\n", f_out);
}
fputs("#", f_out);
v.clear();
fclose(f_out);
}
void Print_symbol()
{
cout << "打印符号表:" << endl;
char temp[num];
ifstream f_in("符号表.txt");
f_in.getline(temp, num, 0);//一次性读入所有符号,保存到temp中
cout << temp << endl;
}
void Print_variable()
{
FILE*f = fopen("标识符表.txt", "w");
cout << endl << "打印标识符表:" << endl;
fputs("标识符表:\n", f);
for (int i = 0;i < VARIABLE.size();i++)
{
cout << fixed << setw(10) << i + 1 << ":" << VARIABLE[i] << " ";
fprintf(f, "%d:%s\n", i + 1, VARIABLE[i].c_str());
if ((i + 1) % 5 == 0)cout << endl;
}
cout << endl;
}
int main()
{
cout << "输入文本名称:" << endl;
cin >> FileName;
LoadSymbol();//加载C语言小子集定义表至map中
LoadFile();
Print_symbol();//打印符号表
Print_variable();//打印标识符表
cout << endl;
return 0;
}


举报

相关推荐

0 条评论