美化你的代码 vb(VBS)代码格式化的实现代码_C语言教程-查字典教程网
美化你的代码 vb(VBS)代码格式化的实现代码
美化你的代码 vb(VBS)代码格式化的实现代码
发布时间:2016-12-28 来源:查字典编辑
摘要:不过VB.NET确实有许多VB6没有的新功能,代码的自动排版就是一项,这也正是我们今天要实现的功能——VB代码格式化。先看下实现的效果:格式...

不过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关键字嘿嘿。好吧,废话少说,直接上代码:

复制代码 代码如下:

#include<iostream>

#include<string>

#include<vector>

#include<algorithm>

#include<fstream>

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 vector<string>& 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)

{

vector<string> 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"

vector<string> 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; i<4; i++)

vecStartKeywords.push_back(_sfpt[i]);

//_pfp 为空

for(auto i=0; i<4; i++)

vecStartKeywords.push_back(_s[0] + " " + _sfpt[i]);

//_s 为空

for(auto i=0; i<4; i++)

for(auto j=0; j<3; j++)

vecStartKeywords.push_back(_pfp[j] + " " + _sfpt[i]);

//_pfp _s 都不为空

for(auto i=0; i<4; i++)

for(auto j=0; j<3; j++)

vecStartKeywords.push_back(_pfp[j] + " " + _s[0] + " " + _sfpt[i]);

//终止关键字 "end if","next","End [Sub | Function | Property | Type]","end with","loop","end select"

vector<string> 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; i<4; i++)

vecEndKeywords.push_back("end " + _sfpt[i]);

//中间关键字 "else","elseif","case"

vector<string> 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, vector<string>& 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)

{

vector<string> 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(indent<0)

indent = 0;

if(indentLevel<0)

indentLevel = 0;

string strIndent;

for(auto i=0; i<indent; 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<<

"-------------------------------------------------------------------"

<<endl<<code<<endl<<endl<<

"-------------------------------------------------------------------"

<<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

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新C语言学习
    热门C语言学习
    编程开发子分类