美化你的代码 vb(VBS)代码格式化的实现代码

____江湖

____江湖

2016-02-19 11:50

下面图老师小编要跟大家分享美化你的代码 vb(VBS)代码格式化的实现代码,简单的过程中其实暗藏玄机,还是要细心学习,喜欢还请记得收藏哦!

不过VB.NET确实有许多VB6没有的新功能,代码的自动排版就是一项,这也正是我们今天要实现的功能——VB代码格式化。
先看下实现的效果:

格式化前:
代码如下:

For i = 0 To WebBrowser1.Document.All.length - 1
If WebBrowser1.Document.All(i).tagName = "HTML" Then
strContent = strContent & WebBrowser1.Document.All(i).innerHTML
Exit For
End If
Next

格式化后:
代码如下:

For i = 0 To WebBrowser1.Document.All.length - 1
If WebBrowser1.Document.All(i).tagName = "HTML" Then
strContent = strContent & WebBrowser1.Document.All(i).innerHTML
Exit For
End If
Next

C++水平一直很烂,所以选择了C++作为练手语言写了这个简陋的VB代码格式化工具。代码不长,才200多行,标准C++实现。另外,为了彻底打消某些人继续使用VC6的念头,使用了auto关键字嘿嘿。好吧,废话少说,直接上代码:
代码如下:

#includeiostream
#includestring
#includevector
#includealgorithm
#includefstream
using namespace std;

//判断是否为空格
bool isSpace(const char chr)
{
return chr == ' ';
}

//去除左侧空白
void leftTrim(string &str)
{
string::iterator p=find_if(str.begin(),str.end(),not1(ptr_fun(isSpace)));
str.erase(str.begin(),p);
}

//去除右侧空白
void rightTrim(string& str)
{
string::reverse_iterator p=find_if(str.rbegin(),str.rend(),not1(ptr_fun(isSpace)));
str.erase(p.base(),str.end());
}

//去除两侧空白
string trim(const string& str)
{
string strRet(str);
leftTrim(strRet);
rightTrim(strRet);
return strRet;
}

//转换成小写
string toLower(const string& str)
{
string strRet(str);
transform(strRet.begin(),strRet.end(),strRet.begin(),(int (*)(int))tolower);
return strRet;
}

//判断是否以给定关键字开头
bool startWith(const vectorstring& vecCodeKeywords,const string& strCodeLine)
{
string line(toLower(strCodeLine));
for(auto keyword=vecCodeKeywords.begin(); keyword!=vecCodeKeywords.end(); keyword++)
if(line.find(*keyword + " ")==0 || line== *keyword)
return true;
return false;
}

//IF...Then...特殊检查
bool checkForIfThen(const string& strCodeLine)
{
vectorstring vecIf;
vecIf.push_back("if");
if(!startWith(vecIf,strCodeLine))
return false;
if(toLower(strCodeLine).find("then")==string::npos)
return false;
string line(trim(toLower(strCodeLine)));
if(line.length()7)
return false;
return !(line.substr(line.length()-4,4) == "then");
}

//格式化给定行并标记相关信息
int formatAndMarkLine(string& strCodeLine)
{
//起始关键字 "if","for","[Private | Friend | Public] [Static] [Sub | Function | Property | Type]","with","do","select"
vectorstring vecStartKeywords;
vecStartKeywords.push_back("if");
vecStartKeywords.push_back("for");
vecStartKeywords.push_back("with");
vecStartKeywords.push_back("do");
vecStartKeywords.push_back("select");
string _pfp[] = {"private","friend","public"}; //可空
string _s[] = {"static"}; //可空
string _sfpt[] = {"sub","function","property","type"};
//_pfp _s 都为空
for(auto i=0; i4; i++)
vecStartKeywords.push_back(_sfpt[i]);
//_pfp 为空
for(auto i=0; i4; i++)
vecStartKeywords.push_back(_s[0] + " " + _sfpt[i]);
//_s 为空
for(auto i=0; i4; i++)
for(auto j=0; j3; j++)
vecStartKeywords.push_back(_pfp[j] + " " + _sfpt[i]);
//_pfp _s 都不为空
for(auto i=0; i4; i++)
for(auto j=0; j3; j++)
vecStartKeywords.push_back(_pfp[j] + " " + _s[0] + " " + _sfpt[i]);

//终止关键字 "end if","next","End [Sub | Function | Property | Type]","end with","loop","end select"
vectorstring vecEndKeywords;
vecEndKeywords.push_back("end if");
vecEndKeywords.push_back("next");
vecEndKeywords.push_back("end with");
vecEndKeywords.push_back("loop");
vecEndKeywords.push_back("end select");
for(auto i=0; i4; i++)
vecEndKeywords.push_back("end " + _sfpt[i]);

//中间关键字 "else","elseif","case"
vectorstring vecMiddleKeywords;
vecMiddleKeywords.push_back("else");
vecMiddleKeywords.push_back("elseif");
vecMiddleKeywords.push_back("case");

auto mark = 0;
char c;
auto n=0;
string line;
auto quote = false; //双引号状态
/*
规则:
双引号内单引号不考虑,否则后面内容成为注释
*/
auto space = true; //空白符状态 false 表示未遇到任何空白符
while((c=strCodeLine[n++]))
{
switch(c)
{
case ' ':
case 't':
if(quote)
{
line += c;
}
else
{
if(!space)
{
line += c;
space = true;
}
}
break;
case '"':
space = false;
quote = !quote;
line += c;
break;
case ''':
space = false;
if(quote)
line += c;
else
{
line += " '"; //MsgBox("itianda") '单引号前有一个空格
while((c=strCodeLine[n++])) //直接附加单引号后面内容
line += c;
continue;
}
break;
case '_': //续行符
space = false;
line += c;
if(!quote && n==(int)strCodeLine.length() && n-2=0 && strCodeLine[n-2]==' ')
mark |= 0x80; //10000000
break;
default:
space = false;
line += c;
}
}
strCodeLine = line;
if(startWith(vecStartKeywords,line) && !checkForIfThen(line))
mark += 1;
if(startWith(vecEndKeywords,line))
mark += 2;
if(startWith(vecMiddleKeywords,line))
mark += 3;
return mark;
}

//将代码按行分割
void splitToLines(const string& strCode, vectorstring& vecCodeLines)
{
vecCodeLines.clear();
char c;
auto n=0;
string line;
while((c=strCode[n++]))
{
if(c!='n')
line += c;
else
{
vecCodeLines.push_back(line);
line.clear();
}
}
if(line.length()) //最后一行为空则舍去
vecCodeLines.push_back(line);
}

//格式化给定代码
void formatCode(string& strCode,const string& strIndentString)
{
vectorstring vecLines; //所有代码行
splitToLines(strCode,vecLines); //获取所有代码行
if(vecLines.size()==0)
{
return;
}
auto indentLevel = 0; //缩进级别
auto incompleteLine = false; //是否是未结束行
for(auto line=vecLines.begin(); line!=vecLines.end(); line++)
{
auto indent = indentLevel;
auto mask = formatAndMarkLine(*line);
switch(mask & ~0x80)
{
case 0:
break;
case 1:
indentLevel++;
break;
case 2:
indent--;
indentLevel--;
break;
case 3:
indent--;
break;
}
if(incompleteLine)
indent++;
incompleteLine = mask & 0x80;
if(indent0)
indent = 0;
if(indentLevel0)
indentLevel = 0;
string strIndent;
for(auto i=0; iindent; i++)
strIndent += strIndentString;
*line = strIndent + *line;
}
strCode.clear();
for(auto line=vecLines.begin(); line!=vecLines.end(); line++)
strCode+= trim(*line).length() ? "n" + *line : "";
}

int main()
{
string indentString = " ";
string code;
ifstream inputFile("in.txt");
string line;
while(getline(inputFile,line))
{
code += line + "n";
}
formatCode(code,indentString);
ofstream outputFile("out.txt");
outputFile"Your beautiful code:"endl
"-------------------------------------------------------------------"
endlcodeendlendl
"-------------------------------------------------------------------"
endl
" Formatted by itianda's PUVBFormatter"
endl
" http://www.programup.com/blog"
endl;
return 0;
}

看过代码应该知道这是多么基本的实现了吧,好多细节都没有去仔细处理,比如没有考虑冒号连接多行的情况,所以如果你希望使用此工具,请不要把多行语句写到一行哦!

最后提供一个我编译好的EXE下载:PUVBFormatter

更新:
增加select case…end select关键字,感谢jjww2999网友的反馈。
本文来自: itianda's blog

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)
展开更多 50%)
分享

猜你喜欢

美化你的代码 vb(VBS)代码格式化的实现代码

编程语言 网络编程
美化你的代码 vb(VBS)代码格式化的实现代码

JS代码的格式化和压缩

Web开发
JS代码的格式化和压缩

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Android日期时间格式国际化的实现代码

编程语言 网络编程
Android日期时间格式国际化的实现代码

CSS代码格式化和压缩的方法与技巧

Web开发
CSS代码格式化和压缩的方法与技巧

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

利用vbs类实现css按钮的代码

Web开发
利用vbs类实现css按钮的代码

java时间戳转日期格式的实现代码

编程语言 网络编程
java时间戳转日期格式的实现代码

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

mssql中得到当天数据的语句

mssql中得到当天数据的语句

C 语言基础教程(一)颜色加亮

C 语言基础教程(一)颜色加亮
下拉加载更多内容 ↓