Fork me on GitHub

C++文件在Html的高亮处理

编译原理最基础的问题便是词法分析器了。下面是我使用C++语言利用迭代器实现的将C++源码转为HTML文件,并实现HighLight

(长期更新,直至成熟)
(较为成熟,不再更新)


版本记录

V-0.2.1 (20180326) 添加对制表符(\t)的支持。

V-0.2.0 (20180325) 优化搜索算法。

V-0.1.4 (20180324) 支持显示代码行数。

V-0.1.3 (20180323) 添加了对多行注释的高亮显示。

V-0.1.2 (20180322) 添加了对单行注释(//)的高亮显示。

V-0.1.1 (20180318) 完善了部分功能,添加了对部分字符(如<、>、&、”、)的支持以及头文件行的高亮显示。

V-0.1.0 (20180317) 只实现了大致功能,对字符(如<、>等)处理还未完善,其次准确的说,这是按照词读入,并不是字母,当然利用迭代器同理可以实现。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iomanip>

using namespace std;

//63个保留字
const int RESERVEWORDNUM = 63;
const string reserveWord[RESERVEWORDNUM] = {
"asm", "auto", "bool", "break", "catch", "case", "char", "class", "const", "const_cast", "continue",
"default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern",
"false", "float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace",
"new", "operator", "private", "protected", "public", "register", "register_cast", "return", "short", "signed",
"sizeof", "static", "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", "typedef",
"typeid", "typename", "union", "unsigned", "using", "virtual", "void", "wchar_t", "volatile", "while"
};

//动态数组
vector<string> reserveWordVector(reserveWord, reserveWord + RESERVEWORDNUM);
//检测是否是保留字
bool isReserveWord(string &word){
vector<string>::iterator itV;
itV = find(reserveWordVector.begin(), reserveWordVector.end(), word);
if ( itV != reserveWordVector.end() ){
return true ;
} else {
return false ;
}
}

void translate(string filename){

ifstream infile; //输入流对象
infile.open(filename + ".cpp");
ofstream outfile; //输出流对象
outfile.open(filename + ".html");

int line = 0; //记录cpp文件行数

if (!infile && !outfile){
cout << "ERROR:打开文件失败!" << endl;
return ;
}

string aLine; //存放cpp文件一行代码
string::iterator lineIte; //定义行迭代器

//读取一行代码
while (getline(infile, aLine)) {

line++; //更新行数

aLine += " "; //每行后添加空白防止迭代器溢出

string aHtmlLine = ""; //html的一行

lineIte = aLine.begin(); //初始化行迭代器指向行首位置

//对该行进行分割,对分割出的字进行检测
while (lineIte != aLine.end()){

string word = ""; //存放一个单词

//行迭代器遇到空格或换行符号时停止并截取单词
while (*lineIte != ' ' && *lineIte != aLine.back()){

//针对html语法,对字符串的处理
if (*lineIte == '<') { word += "&lt;"; }
else if (*lineIte == '>') { word += "&gt;"; }
else if (*lineIte == '&') { word += "&amp;"; }
else if (*lineIte == '\"') { word += "&quot;"; }
else if (*lineIte == '\t') { aHtmlLine += " &nbsp; &nbsp; &nbsp; &nbsp; "; } //处理缩进问题
else { word += *lineIte; }

lineIte++;
}

//检测单行注释
if (*word.begin() == '/' && *(word.begin() + 1) == '/') {
word = "<font color=\"yellow\"><b>" + word + "</b></font>"; //注释为黄色
}

//检测多行注释
if (*word.begin() == '/' && *(word.begin() + 1) == '*') {
word = "<font color=\"yellow\"><b>" + word ; //注释为黄色
}
if (*word.rbegin() == '/' && *(word.rbegin() + 1) == '*') {
word = word + "</b></font>";
}

//检测是否是保留字
if (isReserveWord(word)) {
aHtmlLine += "<font color=\"blue\"><b>" + word + "</b></font>"; //加粗保留字并设置为蓝色
} else {
aHtmlLine += word; //其他字不做处理
}

if (*lineIte == ' ') { lineIte++; aHtmlLine += " "; }
}

//检测是否是头文件行
if (*aLine.begin() == '#') {
aHtmlLine = "<font color=\"green\"><b>" + aHtmlLine + "</b></font>"; //头文件行变绿色
}

outfile << "<font color=\"black\"><b>" << setw(4) << setfill('0') << line << "</b></font>&sdot; &nbsp; &nbsp; &nbsp; &nbsp;" + aHtmlLine + "<br/>" << endl; //写入.html文件
}

infile.close(); //关闭文件流
outfile.close(); //关闭文件流

cout << "转换成功!" << endl;
}

int main(){
cout << "请输入您要转换的cpp文件:";
string cppFileName;
cin >> cppFileName;
translate(cppFileName);
system("pause");
return 0;
}
扫描二维码,拯救贫困山区大学生!
-------------本文结束感谢您的阅读-------------