KMyaccが生成するコードがグローバル変数だらけなのでクロージャで隠蔽する


http://www005.upp.so-net.ne.jp/kmori/kmyacc/kmyacc.html
KMyaccユーザーズガイド
を参考に

気になったので手を加えてみた
kmyacc.js.parserを展開してコードが生成されるのでこれを適当にほげほげする

$semval($) yyval
$semval($,%t) yyval
$semval(%n) yyastk[yysp-(%l-%n)]
$semval(%n,%t) yyastk[yysp-(%l-%n)]
$include;

/* Prototype file of JavaScript parser.
 * Written by MORI Koichiro
 * This file is PUBLIC DOMAIN.
 */
var parser = function(){ //ここからクロージャの中
var buffer;
var token;
var toktype;

//〜略〜(べたっとyyparseの後まで貼る)

$tailcode;

return{
	parse: function(str){
		output = "";
		var start = (new Date()).getTime();
		scanner.init(str);
		yyparse();
		var end   = (new Date()).getTime();
		if(yydebug) logger.info( "total:" + ( end - start ) + "ms");
		
		return {
			"output": output,
			"log": logger.buffer
			};
	}
};
}();

みたいにしてやるとスッキリしていい感じ


yydocopenとかは使わないかなーと思ったので消して全体のログ機能にまとめた


$tailcodeは

var output;

//適当なスキャナの定義
var scanner = new Scanner();

function Logger(){
	this.initialize.apply(this, arguments);
}
Logger.prototype = {
	initialize: function(){
		this.buffer = new FString();
	},
	fatal: function(str){
		this.buffer.append("[FATAL]", str, "\n");
	},
	warn: function(str){
		this.buffer.append("[WARN]", str, "\n");
	},
	info: function(str){
		this.buffer.append("[INFO]", str, "\n");
	}
};
var logger = new Logger();

function yylex(){
	yylval = scanner.get();
	if(yydebug) logger.info("yylex() -> " + yylval);
	return yylval[0];
}

function yyerror(msg) {
  logger.fatal("error:[" + msg + "] on line:" + (scanner.line) + "[" + scanner.buffer[scanner.line - 1] + "]");
}

のようにして使っている


あと、yyparseのなかのyystateとかもvarをつけておいた方がいい
気になっていじったのはそのあたりまで