forked from: forked from: getToken

by tepe forked from forked from: getToken (diff: 70)
かっこ抽出 {}

原文

FPS計測    
Wonderfl.capture(stage);
原文テキスト入力ボックス
♥0 | Line 302 | Modified 2013-05-31 13:24:01 | MIT License
play

ActionScript3 source code

/**
 * Copyright tepe ( http://wonderfl.net/user/tepe )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/3ZlL
 */

// forked from tepe's forked from: getToken
// forked from tepe's getToken
/*
かっこ抽出 {}


*/
package {
    import flash.utils.Dictionary;
    import flash.display.*;
    import flash.text.*;
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;
    import net.hires.debug.Stats;
    


    public class FlashTest extends Sprite {
        private var t1:TextField = new TextField();//原文
        private var t2:TextField = new TextField();
        
        public function FlashTest() {
            // write as3 code here..
            init();
            //FPS計測    
            addChild( new Stats() );
            //Wonderfl.capture(stage);
            onChange(null);
            
        }
        
 
        private function init():void{
            //原文テキスト入力ボックス
            t1.border = true;
            t1.width = 230;
            t1.height = 360;
            t1.y=100;
            t1.type = "input";
            t1.multiline = true;
            t1.text = "package {\n\timport flash.utils.Dictionary;\n\timport flash.display.*;\n\t";
            t1.appendText("public class FlashTest extends Sprite {\n\t\t");
            t1.appendText("init();\n\t\tcnChange(null);");
            t1.appendText("\n\t}");
            t1.appendText("\n}");
            addChild(t1);
            t1.addEventListener(Event.CHANGE,onChange);
            t2.x = 230;
            t2.width=230;
            t2.height=460;
            t2.wordWrap =true;
            t2.multiline=true;
            t2.border = true;
            addChild(t2);

            
        }
        
        

        private var tk:token;
        private var list:Array;
        private var stack:Array;
        private function onChange(e:Event=null):void{
            list = new Array();
            stack = new Array();
            var cnt:int=0;
            var cnt2:int=0;
            tk = new token();
            stack.push(new Array());
            var i:int;
            var index:int=0;
            var len:int = t1.length;
            tk.getToken(t1.text);
            //var cnt:int=0;
            t2.text = "";//tk.list.length.toString();
            stack[stack.length-1].push(index2);//ステップカウント
            for(i=0;i<tk.length;i++){
                //記号の処理
                if(tk.getType(i) == token.MARK){
                    var s:String = tk.getString(i);
                    var index2:int = i;
                    if(s == ";"){ 
                        cnt++;
                        stack[stack.length-1].push(index2);//ステップカウント
                    }
                    else if(s=="{"){ 
                        cnt2++;
                        stack.push(new Array());
                        stack[stack.length-1].push(index2);//ライン開始
                    }
                    else if(s=="}"){

                        cnt++;
                        stack[stack.length-1].push(index2);//ライン終了
                        list.push(stack.pop());
                        stack[stack.length-1].push(index2);//ステップカウント
                    }
                    
                }

                //if(tk.getType(i) != 0)t2.text += tk.getString(i)+" ";                
                //t2.text+= "["+tk.getType(i)+"]\n";
                //t2.text += i.toString()+" ---\n";
            }
            stack[stack.length-1].push(tk.length);//ステップカウント
            list.push(stack.pop());//ルート
            for(i=0;i<list.length;i++){
                t2.text += "line"+(i+1)+":  ";//list[i].length.toString()+"\n";
                var ar:Array = list[i];
                for(var j:int=0;j<ar.length;j++){
                    t2.text += ar[j].toString()+" ";
                }
                t2.text += "\n";

            }

            t2.text+="step:"+cnt.toString()+"\n";
            t2.text+="line:"+cnt2.toString()+"\n";
        }
        
        


    }
}



//////////////////////////////////////////////////////////////////////////
//  トークン列取得
//////////////////////////////////////////////////////////////////////////
import flash.display.*;
import flash.events.*;



//テキストからトークンを抽出する
class token{
    private var tokenString:Array;//トークン文字列
    private var tokenType:Array;//トークンタイプ
    private var _length:int;
    private var source:String;
    public static const ERROR:int = -1;//エラー
    public static const SPACE:int = 0;//スペース
    public static const COMMENT:int = 1;//コメント 
    public static const VALUE:int = 2;//数値
    public static const WORD:int = 3;//識別子
    public static const TEXT:int = 4;//文字列
    public static const MARK:int = 5;//記号
    public static const OTHER:int = 6;//その他(マルチバイトの文字列)
    public function token(){    
    }

    //指定インデクスからmax個までトークン抽出
    //抽出したトークンはlistに追加
    //抽出したところまでのインデクスを返す
    public function getToken(str:String,index:uint=0):int{
        
        source=str;
        tokenString = new Array();
        tokenType = new Array();
        index01=0;
        
        var i:int = 0;
        while(i<str.length){
            i = func01();
        }
        _length = tokenString.length;
        return _length;
    }
    public function get length():int{
        return _length;
    }

    
    //トークン文字列取得
    public function getString(index:int):String{
        var str:String=null;
        if(0<=index && index < tokenString.length)str = tokenString[index];
        return str;
    }
    //トークンタイプ取得
    public function getType(index:int):int{
        var type:int=-2;
        if(0<=index && index < tokenType.length){ 
            type = tokenType[index];
        }
        return type;
    }


    //トークン列に追加
    private function addToken(str:String,type:int):int{
        tokenString.push(str);
        tokenType.push(type);
        return tokenString.length;
    }


//-------------------------------------------------------------
    //開始インデクスを受け取りトークンのタイプを返す
    private var index01:int=0;
    private function func01():int{//
        if(index01 >= source.length)return source.length;
        var index:int = index01;
        //var token:Object = new Object();
        var type:int;//トークンタイプ
        var str:String;//トークン文字列
        var reg:RegExp = new RegExp();                
        var result:Object;
        //list.push(token);
        //トークンタイプ:空白か?
        if(    source.charAt(index)== " " ||
               source.charAt(index)=="\t" ||
               source.charAt(index)=="\n" ||
               source.charAt(index)=="\r" ){
                   type = SPACE;
                   reg = /[^\s]/mg;
                   reg.lastIndex = index;
                   result = reg.exec(source);
                   //トークン作成
                   if(result == null){//
                       str = source.substring(index,source.length);
                       index01 = source.length;//次の開始位置
                   }
                   else{//
                       str = source.substring(index,result.index);
                       index01 = result.index;                       
                   }
                   addToken(str,type);
                   return index01;
                                       
               }

        
        //トークンタイプ:文字列定数1
        if(source.charAt(index)== "'"){
            type = TEXT;
            var indexA:int = index;
            reg = /['\n\r]/mg;//改行か次の[']が現れる位置
            do{//エスケープ処理
                reg.lastIndex = indexA+1;
                result = reg.exec(source);
                if(result==null)break;
                else indexA = result.index;
            }while(source.charAt(indexA-1)=="\\");//["]が現れてもその前がエスケープなら再検索
            
            //トークン作成
            if(result == null){//エラー
                str = "'";
                type = ERROR;
                index01 = index+1;//次の開始位置
            }
            else{//
                str = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
            }
            addToken(str,type);
            return index01;
                
        }
 
        //トークンタイプ:文字列定数2
        if(source.charAt(index)== '"'){
            type = TEXT;
            var indexB:int = index;
            reg = /["\n\r]/mg;//改行か次の["]が現れる位置
            do{//エスケープ処理
                reg.lastIndex = indexB+1;
                result = reg.exec(source);
                if(result==null)break;
                else indexB = result.index;
            }while(source.charAt(indexB-1)=="\\");//["]が現れてもその前がエスケープなら再検索
            
            //トークン作成
            if(result == null){//エラー
                str = '"';
                type = ERROR;
                index01 = index+1;//次の開始位置
                
            }
            else{//
                str = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
                
            }
            addToken(str,type);
            return index01;
        }
        
        if(source.charAt(index)== "/"){
               //一行コメント
               if(source.charAt(index+1)== "/"){//
                   reg = /[\n\r]/mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   //トークン作成
                   type = COMMENT;
                   if(result == null){
                       str = source.substring(index,source.length);
                       index01 = source.length;//次の開始位置                       
                   }
                   else{// 
                       str = source.substring(index,result.index);
                       index01 = result.index;//次の開始位置
                   }
                   addToken(str,type);
                   return index01;
               }
               //複数行コメント
               if(source.charAt(index+1)== "*"){
                   reg = /\*\//mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   
                   //トークン作成
                   type = COMMENT;
                   if(result == null){//エラー
                       type = ERROR;
                       str = '/*';
                       index01 = index+2;//次の開始位置
                   }
                   else{//
                       str = source.substring(index,result.index+2);
                       index01 = result.index+2;//次の開始位置                       
                   }
                   addToken(str,type);
                   return index01;
               }
        }

        //英数字
        if((source.charCodeAt(index) > 64 && source.charCodeAt(index) < 91) ||// A-Z
           (source.charCodeAt(index) > 96 && source.charCodeAt(index) < 123)||// a-z
            source.charCodeAt(index) == 95 ){// _
                reg = /[^a-zA-Z0-9_]/mg;//英数字以外が現れる位置
                reg.lastIndex = index+1;
                result = reg.exec(source);
                type = WORD;
                if(result == null){//eof
                    str = source.substring(index,source.length);
                    index01 = source.length;
                }
                else{//
                    str = source.substring(index,result.index);
                    index01 = result.index;//次の開始位置
                }
                addToken(str,type);
                return index01;
                
        }
        
        
        //数値
        if(source.charCodeAt(index) > 47 && source.charCodeAt(index) < 58){
            reg = /[^a-zA-Z0-9_.]/mg;
            reg.lastIndex = index+1;
            result = reg.exec(source);
            type = VALUE;
            if(result == null){//eof
                str = source.substring(index,source.length);
                index01 = source.length;
            }
            else{// 
                str = source.substring(index,result.index);
                index01 = result.index;//次の開始位置
            }
            //num();//種類判別
            addToken(str,type);
            return index01;

        }
        
        //半角記号
        if(source.charCodeAt(index)<127 && source.charCodeAt(index)>32){
            type = MARK;
            str = source.charAt(index);
            index01 = index+1;
            
            addToken(str,type);
            return index01;
        }
    
        //その他文字列 マルチバイト文字等はここに入る
        type = OTHER;
        reg = /[\x01-\x7f]/mg;
        reg.lastIndex = index+1;
        result = reg.exec(source);
        if(result == null){//eof
            str = source.substring(index,source.length);
            index01 = source.length;
        }
        else{// 
            str = source.substring(index,result.index);
            index01 = result.index;//次の開始位置
        }
        
        addToken(str,type);
        return index01;
    }
     
}//class

Forked