一、实验内容及要求:
(1)功能:实现具有个人风格C++源代码的预编译系统,即扫描程序把具有个人风格的单词重新改写为传统C++单词。
改写的单词至少应该有:
原C++语言的单词 具有个人风格的C++语言的单词
int integer
float real
cin read
cout write
== =
= :=
!= <>
{ begin
} end
/* */ (* *)
(2)打开一个具有个人风格的C++源文件,把具有个人风格的单词重新改写为传统C++的单词,并存盘。(预编译)
(3)对改写好的C++程序进行编译并执行。
(4)要求应用程序应为Windows界面。
(1)功能:实现具有个人风格C++源代码的预编译系统,即扫描程序把具有个人风格的单词重新改写为传统C++单词。
改写的单词至少应该有:
原C++语言的单词 具有个人风格的C++语言的单词
int integer
float real
cin read
cout write
== =
= :=
!= <>
{ begin
} end
/* */ (* *)
(2)打开一个具有个人风格的C++源文件,把具有个人风格的单词重新改写为传统C++的单词,并存盘。(预编译)
(3)对改写好的C++程序进行编译并执行。
(4)要求应用程序应为Windows界面。
(5)应该书写完善的软件文档。
二.设计思路
1.将cpp文件中的标识符分位两类,第一类是单独一个标识符成一个word的,如integer,real等,左右都是空格,不会接其他字符,第二类标识符是会和其他字符组合成一个word的,如read>>i,if(i<>3)等。
2.对于第一类标识符,我用C++map容器实现一对一的映射,对于第二类的标识符,用正则表达式匹配,匹配成功的token再进行标识符的替换。
3.对结果进行存盘。
三.源代码
#include <fstream>
#include <iostream>
#include <map>
#include <regex>
#include <sstream>
using namespace std;
map<string, string> words; //保存标识符(左右不会有其他字符的标识符)转换
regex match1(".*(<>).*"); //设置各匹配规则
regex match2(".*(:=).*");
regex match3(".*(=).*");
regex match4(".*(read).*");
regex match5(".*(write).*");
regex match6("(\\(\\*).*(\\*\\))");
void init() {
words.insert(make_pair("integer", "int"));
words.insert(make_pair("real", "float"));
words.insert(make_pair("begin", "{"));
words.insert(make_pair("end", "}"));
// 其余的用正则匹配
}
string match_logic(string word) {
//正则表达式匹配规则
string result = "";
if (regex_match(word, match1))
result = word.replace(word.find("<>"), 2, "!=");
else if (regex_match(word, match2))
result = word.replace(word.find(":="), 2, "=");
else if (regex_match(word, match3))
result = word.replace(word.find("="), 1, "==");
else if (regex_match(word, match4))
result = word.replace(word.find("read"), 4, "cin");
else if (regex_match(word, match5))
result = word.replace(word.find("write"), 5, "cout");
return result;
}
int main() {
init();
ifstream infile;
ofstream outfile("Test-out.cpp");//用来存盘的文件
infile.open("Test-in.cpp");
string line = "";
string word;
char buff[1024];
string temp;
if (infile.is_open()) {
while (!infile.eof()) {
infile.getline(buff, 1024); //逐行从文件中读取
line = buff;
temp = line.substr(0, line.length() - 1); //先判断是不是注释
if (regex_match(temp, match6)) {
word = "/*" + temp.substr(2, temp.find_last_of("*") - 2) + "*/";
cout << word << endl;
outfile << word << endl; //保存至文件中
continue;
}
istringstream stream(line); //字符串流做输入流
while (stream >> word) {
if (words.count(word) != 0) { //判断是否是单独成组的标识符
cout << words[word] << " ";
outfile << words[word] << " ";
if (words[word] == "end")
break;
} else if ((temp = match_logic(word)) !=
"") //判断该word是否符合正则匹配规则
{
cout << temp << " ";
outfile << temp << " ";
} else {
cout << word << " ";
outfile << word << " ";
}
}
cout << endl; //该行处理结束,转入下一行
outfile << endl;
}
}
return 0;
}