UWSCスクリプトのフォーマッター
公式掲示板にインデントをタブで貼り付ける人がいるので、フォーマッターを考えた。
フォーマッターと言っても、インデントを整えるだけ。
でも、構文解析してますよ!
構文解析エンジン
wshでやろうと思ったので、javascriptのパーサージェネレーターを探したところ、見つけた。
JavaScript で構文解析: Days on the Moon
俄然やる気に。
ということでスクリプト
<?xml version="1.0" standalone="yes" ?> <package> <job id="Formatter"> <?job error="true" debug="true"?> <runtime> <description>UWSCスクリプトファイルのインデントを行います</description> <unnamed name="target" helpstring="対象スクリプト" many="false" required="false" /> </runtime> <resource id="indent"> </resource> <script language="JScript" src="gin.js" /> <object id="_fso" progid="Scripting.FileSystemObject"/> <script language="JScript"> <![CDATA[ WScript.Quit((function() { // wscriptの場合は引数必須。cscriptの場合は引数なければ標準入力 var tarPath = null, tarScript; if(WScript.Arguments.length) tarPath = WScript.Arguments(0); if(tarPath != null) { try { var tarFile = _fso.OpenTextFile(tarPath); tarScript = tarFile.ReadAll(); tarFile.Close(); } catch(e) { WScript.Echo(e.name, e.number, e.message); return e.number; } } else if(WScript.FullName.toLowerCase().slice(-11) == "cscript.exe") { try { tarScript = WScript.StdIn.ReadAll(); } catch(e) { if(e.number != -2146828226) WScript.Echo(e.name, e.number, e.message); return e.number; } } else { return 1; } // 構文解析 tarScript = tarScript.replace(/\n\r/g, "\n\0\r").replace(/^\r/, "\t\r"); var indent = getResource("indent") var uwscParser = new Gin.Grammar({ Statement: / (Sep (IndentNon | IndentStart | IndentSep | IndentEnd | Comment | All | $EPS):push ('\r\n' | ';'))* /, Sep: / <[ \t ]*> /, All: / <([^\r\n";]|"[^\r\n"]*")+> /, Tail: / Sep (Comment | $EPS) /, IndentNon: / <[iI][fF][ \t ][\S \t ]+[ \t ][tT][hH][eE][nN]> Sep Name (All | $EPS) /, IndentStart:/ ((<[mM][oO][dD][uU][lL][eE]> | <[cC][lL][aA][sS][sS]> | <[tT][eE][xX][tT][bB][lL][oO][cC][kK]> ) Sep Name | <[tT][rR][yY]> | (<[pP][rR][oO][cC][eE][dD][uU][rR][eE]> | <[fF][uU][nN][cC][tT][iI][oO][nN]> | <[fF][oO][rR]> | <[wW][hH][iI][lL][eE]> | <[sS][eE][lL][eE][cC][tT]> | <[wW][iI][tT][hH]> ) Sep All | <[iI][fF][bB]?[ \t ][\S \t ]+[ \t ][tT][hH][eE][nN]> | <[rR][eE][pP][eE][aA][tT]> | <[cC][oO][mM][_][eE][rR][rR][_][iI][gG][nN]> ) Tail ::inc /, IndentSep: / (<[fF][iI][nN][aA][lL][lL][yY]> | <[eE][xX][cC][eE][pP][tT]> | <[eE][lL][sS][eE][iI][fF]> Sep All | <[eE][lL][sS][eE]> | <[cC][aA][sS][eE]> Sep All | <[dD][eE][fF][aA][uU][lL][tT]>) Tail ::sep /, IndentEnd: / ( <[eE][nN][dD][mM][oO][dD][uU][lL][eE]> | <[eE][nN][dD][cC][lL][aA][sS][sS]> | <[eE][nN][dD][wW][iI][tT][hH]> | <[eE][nN][dD][tT][eE][xX][tT][bB][lL][oO][cC][kK]> | <[eE][nN][dD][tT][rR][yY]> | <[fF][eE][nN][dD]> | <[eE][nN][dD][iI][fF]> | <[nN][eE][xX][tT]> | <[wW][eE][nN][dD]> | <[uU][nN][tT][iI][lL]> Sep All | <[sS][eE][lL][eE][nN][dD]> | <[cC][oO][mM][_][eE][rR][rR][_][rR][eE][tT]> ) Tail ::dec /, Dim: / <[dD][iI][mM]> Sep Params /, Comment: / '\/\/' <[^\r\n]*> /, Params: / Name (Sep '=' Sep Val | $EPS) (Sep ',' Sep Name (Sep '=' Sep Val | $EPS))* /, Name: / <[a-zA-Z#%&~|\@{}][0-9a-zA-Z#%&~|\@{}]*> /, Val: / $DECIMAL | '"' <[^"]*> '"' / }, "Statement", '_\r\n'); var ua = { _s: [], _is: [], _i: 0, _n: 0, inc: function() { this._i++; this._n=-1; }, dec: function() { this._i--; }, sep: function() { this._n=-1; }, push: function(v) { this._s.push(v); this._is.push(this._i + this._n); this._n=0; } }; // フォーマット開始 var match = uwscParser.parse(tarScript, ua); if(match && match.full) { // 結果出力 var i, j, line; var join = function(v) { var ret = v; if(v instanceof Array) { ret = ""; for(var i = 0; i < v.length; i++) ret += join(v[i]); } return ret; }; for(i = 0; i < ua._s.length; i++) { line = join(ua._s[i]); line = line.replace(/^[ \t ]+/, ''); for(j = 0; j < ua._is[i]; j++) line = indent + line; WScript.Echo(line); } } else { WScript.Echo("スクリプト解析失敗") } })()); ]]> </script> </job> </package>
拡張子「.wsf」で保存してください。
また、同フォルダーに、上記リンクのgin.jsが必要です。