JC; 5C(1,2,3,4); 3C; 236C;
JC ; 5C ( 1 , 2 , 3 , 4 ) ; 3C ; 236C ;
SingleToken = function(c){
this.type = this.value = c;
}
WordToken = function(text){
this.type = /\D/.test(text) ? "WORD" : "NUMBER";
this.value = text;
}
SINGLE_TOKENS = new Array();
SINGLE_TOKENS["("] = new SingleToken("(");
SINGLE_TOKENS[")"] = new SingleToken(")");
SINGLE_TOKENS[";"] = new SingleToken(";");
SINGLE_TOKENS[","] = new SingleToken(",");
SINGLE_TOKENS[">"] = new SingleToken(">");Lexer = function(input){
this.text = input;
this.current = null;
this.nextToken();
}
Lexer.prototype.nextToken = function(){
if(this.text.match(/\S/)){
if(RegExp.lastMatch in SINGLE_TOKENS){
this.text = RegExp.rightContext;
this.current = SINGLE_TOKENS[RegExp.lastMatch];
return this.current;
}
if(this.text.match(/^\s*(\w+)/)){
this.text = RegExp.rightContext;
this.current = new WordToken(RegExp.$1);
return this.current;
}
}
this.current = null;
return null;
}
Lexer.prototype.skip = function(type){
if(this.current && this.current.type == type){
var prev = this.current;
this.nextToken();
return prev;
}
else{
return null;
}
} run = function(text){
var lex = new Lexer(text);
while( lex.current ){
window.alert(lex.current.type);
lex.nextToken();
}
}
run("JC; 5C(1,2,3,4); 3C; 236C;") Lexer = function(input){
this.enabled = true; // 使用可能か否か
this.text = input;
this.current = null;
this.nextToken();
}
Lexer.prototype.nextToken = function(){
if(this.enabled && this.text.match(/(\S)(.*)/)){
if(RegExp.$1 in SINGLE_TOKENS){
this.text = RegExp.$2;
this.current = SINGLE_TOKENS[RegExp.$1];
return this.current;
}
if(this.text.match(/^\s*(\w+)/)){
this.text = RegExp.rightContext;
this.current = new WordToken(RegExp.$1);
return this.current;
}
}
this.enabled = false; // 使用不可能にする
this.current = null;
return null;
}
Lexer.prototype.skip = function(type){
var prev = this.softskip(type);
if(prev == null){
this.enabled = false; // 使用不可能にする
}
return prev;
}
Lexer.prototype.softskip = function(type){
if(this.enabled && this.current.type == type){
var prev = this.current;
this.nextToken();
return prev;
}
else{
return null;
}
}
Lexer.prototype.abort = function(){
this.enabled = false;
} | Field summary | |
| enabled | このLexerがまだ使用可能なら true。 このフィールドが true である限り、current は決して null ではない |
| current | 一番最後に読み込んだトークン(残ってなければ null )。 nextToken() や skip() などを実行したとき変更される。 |
| text | 解析対象であるテキスト |
| Method summary | |
| abort() | このオブジェクトを使用不可能にする |
| nextToken() | 新しいトークンを読み出して返す。 失敗時は null を返すと共に、このオブジェクトを使用不可能にする |
| skip(type) | current が指定された種類のトークンならそれを読み飛ばす。 失敗時は null を返すと共に、このオブジェクトを使用不可能にする |
| softskip(type) | skip(type) と同じだが、失敗しても使用不可能にならない |