середу, 28 липня 2010 р.

Лексический анализатор

function lexer(config){
var stack=[""];
var data=(function(config){
var data={};
for(var state in config){
data[state]=(function(src){
for(var a=[],i=0;i<src.length;i++){
var re=src[i][0];
var fn=src[i][1];
if(re instanceof RegExp)
re=new RegExp("^("+re.source+").*",'m');
else re=new RegExp("^("+re+").*",'m');
if(!(fn instanceof Function))
fn=new Function("",fn);
a.push([re,fn]);
}
return a;})(config[state]);
}
return data;})(config);
var control={
begin:function(state){
if(state in config)
stack[0]=state;
else throw "wrong state";
},
push:function(){
if(state in config)
stack.unshift(state);
else throw "wrong state";
},
pop:function(){return stack.shift();},
top:function(){return stack[0];},
}
function lex(text){
while(text.length>0){
var token=step.apply(this,[text]);
puts(token);
if(token)
text=text.substring(token.length);
}
}
function step(text){
var current=data[stack[0]];
var token;
for(var ci in current)if(token=(function(re,fn){
var match=re(text);
var token=match&&match[1];
if(token){
control.text=token;
fn.apply(this,[control]);
return token;
}
})(current[ci][0],current[ci][1]))return token;
throw "not found";
}
return lex;}


Немає коментарів:

Дописати коментар