flash on 2012-6-12

by tepe
♥0 | Line 464 | Modified 2012-06-13 07:53:52 | 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/7ByL
 */

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();
        private var color1:uint = 0x223388;//
        private var color2:uint = 0x4488ff;
        
        public function FlashTest() {
            // write as3 code here..
            init();
            //FPS計測    
            //addChild( new Stats() );
            Wonderfl.capture(stage);
            onChange(null);
            
        }
        
 
        private function init():void{
            //原文テキスト入力ボックス
            graphics.beginFill(0);
            graphics.drawRect(0,0,466,466);
            graphics.endFill();
            t1.border = true;
            t1.textColor=color2;
            t1.borderColor = color1;
            t1.width = 230;
            t1.height = 360;
            t1.y=100;
            t1.type = "input";
            t1.multiline = true;
            t1.text = "1234567890;\n{test}\nあいうえお test";
            t1.appendText("\n 0xffffff");
            addChild(t1);
            t1.addEventListener(Event.CHANGE,onChange);
            t2.textColor = color2;
            t2.borderColor = color1;
            t2.x = 230;
            t2.width=230;
            t2.height=460;
            t2.wordWrap =true;
            t2.multiline=true;
            t2.border = true;
            addChild(t2);

            
        }
        
        

        private var tk:tokenList;
        private function onChange(e:Event=null):void{
            var cnt:int=0;
            tk = new tokenList();
            
            var i:int;
            var index:int=0;
            var len:int = t1.length;
            var list:Array = tk.getToken(t1.text);
            var slist:Array = tk.setBlock();
            var exp:expList = new expList();
            var el:Array;
            el = exp.setToken(list);
            t2.text = "";//tk.list.length.toString();
            //t2.appendText(list.length.toString());
            t2.appendText(el.length.toString()+"\n");
            for(i=0;i<el.length;i++){ 
                //t2.appendText(el[i].length.toString());
                for(var j:int=0;j<el[i].length;j++){ 
                    t2.appendText(el[i][j].text);
                }

                t2.appendText("\n");
            }


            
            //t2.appendText(slist.length+"\n");
            
            /*for(i=0;i<slist.length;i++){ 
                t2.appendText(slist[i].entry.toString()+"--"+slist[i].exit.toString()+ "\n");
            }

            for(i=0;i<list.length;i++){
                t2.appendText(list[i].text+"\n"); 
            }*/


        }
        
        


    }
}



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

//プログラム式を扱う
class expList{
    public var list:Array;
    private var tokenList:Array;
    public function expList(){
        list = new Array();
    }
    //式リスト生成
    public function setToken(token:Array):Array{
        tokenList = token;
        // 式の区切りを探す ; {}
        var exp:Array = new Array();
        var i:int;
        var stat:Array = new Array();
        for(i=0;i<token.length;i++){ 
            
            if(token[i].text == ";"){
                list.push(exp);
                exp = new Array();
                continue;
            }
                
            if(token[i].type != "block"){
                exp.push(token[i]);
                continue;
            }
            else{//記号
                
                
                if(token[i].text == "{"){
                    i=aaa(i);
                    list.push(exp);
                    exp = new Array();
                    continue;
                }
                else if(token[i].text == "("){
                    i=aaa(i);
                    continue;
                }
                else if(token[i].text == "["){
                    i=aaa(i);
                    continue;
                }


                else{
                    exp.push(token[i]);
                    continue;
                }
            }
            
        }
        return list;

    }
    //ブロックの開始から終わりまで飛ばす
    public function aaa(n:int):int{
        var stat:Array = new Array();
        var i:int=n;
        if(tokenList[i].type != "block")return n;
        
        do{
            if(tokenList[i].type != "block"){
                i++;
                continue;
            }

            if(tokenList[i].text == "{") stat.push(tokenList[i]);
            else if(tokenList[i].text == "(")stat.push(tokenList[i]);
            else if(tokenList[i].text == "[")stat.push(tokenList[i]);
            else if(tokenList[i].text == "}"){ 
                if(stat[stat.length-1].text == "{")stat.pop();
                else return tokenList.length-1;
            }
            else if(tokenList[i].text == ")"){ 
                if(stat[stat.length-1].text == "(")stat.pop();
                else return tokenList.length-1;
            }
            else if(tokenList[i].text == "]"){ 
                if(stat[stat.length-1].text == "[")stat.pop();
                else return tokenList.length-1;
            }
            i++;
        }while(stat.length>0 && i<tokenList.length-1);

        return i-1;
    }



}


//テキストからトークンを抽出する
class tokenList{
    private var list:Array;//トークン列
    private var source:String;
    //トークンタイプ
    public static const OTHER:int = -1;//その他
    //一回目の分類
    public static const SPACE:int = 0;//空白
    public static const STRING:int = 1;//文字列定数
    public static const COMMENT:int = 2;//コメントアウト
    public static const ELEMENT:int = 3;//それ以外の要素
    
    public static const NUMBER:int = 10;//数値
    public static const INTEGER:int = 11;//整数
    public static const REAL:int = 12;//実数
    public static const HEX:int = 13;//16進数表記
    public static const OCT:int = 14;//8進数表記
    public static const BINARY:int = 15;//2進数表記
    
    public static const SIGN:int = 20;//記号要素
    public static const SCOPE:int = 21;//スコープ
    public static const ENTRY:int = 22;//スコープ開始位置
    public static const EXIT:int = 23;//スコープ終了
    
    public static const ACCESS:int = 40;//アクセス修飾子
    public static const PRIVATE:int = 41;
    public static const PUBLIC:int = 42;
    public static const PROTECTED:int = 43;
    
    public static const VAR:int = 50;//変数宣言
    public static const FUNCTION:int = 51;//関数定義
    public static const CONST:int = 52;//定数宣言
    
    public static const CREATE:int = 60;//新しい要素生成
    //public static const 
    
    public function tokenList(){    
        
    }

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

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

        
        //トークンタイプ:文字列定数1
        if(source.charAt(index)== "'"){
            token.type = STRING;
            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){//エラー
                token.text = "'";
                token.type = OTHER;
                index01 = index+1;//次の開始位置
                return index01;
            }
            else{//
                token.text = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
                return index01;
            }
                
        }
 
        //トークンタイプ:文字列定数2
        if(source.charAt(index)== '"'){
            token.type = STRING;
            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){//エラー
                token.text = '"';
                token.type = OTHER;
                index01 = index+1;//次の開始位置
                return index01;
            }
            else{//
                token.text = source.substring(index,result.index+1);
                index01 = result.index+1;//次の開始位置
                return index01;
            }
        }
        
        
        //コメントアウト
        if(source.charAt(index)== "/"){
               //一行コメント
               if(source.charAt(index+1)== "/"){//
                   reg = /[\n\r]/mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   //トークン作成
                   token.type = COMMENT;
                   if(result == null){
                       token.text = source.substring(index,source.length);
                       index01 = source.length;//次の開始位置
                       return index01;
                       
                   }
                   else{// 
                       token.text = source.substring(index,result.index);
                       index01 = result.index;//次の開始位置
                       return index01;
                   }
               }
               //複数行コメント
               if(source.charAt(index+1)== "*"){
                   reg = /\*\//mg;
                   reg.lastIndex = index+2;
                   result = reg.exec(source);
                   
                   //トークン作成
                   token.type = COMMENT;
                   if(result == null){//エラー
                       token.type = OTHER;
                       token.text = '/*';
                       index01 = index+2;//次の開始位置
                       return index01;
                   }
                   else{//
                       token.text = source.substring(index,result.index+2);
                       index01 = result.index+2;//次の開始位置
                       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);
                
                token.type = ELEMENT;//半角英数字
                if(result == null){//
                    token.text = source.substring(index,source.length);
                    index01 = source.length;//次の開始位置
                    return index01;
                }
                else{//
                    token.text = source.substring(index,result.index);
                    index01 = result.index;//次の開始位置
                    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);
            
            token.type = NUMBER;//半角英数字
            if(result == null){
                token.text = source.substring(index,source.length);
                index01 = source.length;//次の開始位置
                //return index01;
            }
            else{// 
                token.text = source.substring(index,result.index);
                index01 = result.index;//次の開始位置
                //return index01;
            }
            num();//種類判別
            return index01;

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

//数値の処理
//-------------------------------------------------------------------
    private function num():void{
        var token:Object= list[list.length-1];
        var index:int = token.index;
        
        
        //0~9だけなら整数値。小数点が1つだけあるなら実数値。どちらにも該当しなければ数値ではない。
                if(token.text.search(/[^0-9]/mg)== -1){//数字のみ →整数値or8進数
                    if(token.text.charAt(0)=="0" && 1<token.text.length){//0から始まれば8進数かも(ただし0以降に数字があれば)
                        if(token.text.search(/[^0-7]/mg)!= -1){//0から始まったけど8進数ではなかった
                            token.type = OTHER;
                            token.tag += "oct:1\n";
                        }
                        //8進数確定
                        token.tag += "oct\n";
                        token.value = uint(parseInt(token.text,8));
                    }
                    //整数
                    token.tag += "int\n";
                    token.value = uint(parseInt(token.text));
                }
                else{
                    var a:Array = token.text.match(/[.]/mg);//小数点が1つだけなら実数。それ以外はよくわからない何か。
                    if(a.length == 1){//実数値
                        if(token.text.search(/[^0-9.]/mg) != -1 || //数字と小数点以外の文字が入ってたらNG
                            token.text.search(/[.]/mg) == token.text.length-1){//小数点で終わってたらNG
                            token.type = OTHER;
                            token.tag += "real:NG1\n";
                        }

                        token.tag += "real\n";
                        token.value = Number(token.text);
                    }
                    else{//整数、実数以外
                        if(token.text.charAt(0)=="0"){//
                            //2進
                            if(token.text.charAt(1)=="b" || token.text.charAt(1)=="B"){
                                a = token.text.match(/[^01]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = OTHER;
                                else{
                                    token.tag += "bin\n";
                                    var bin:String = token.text.substring(2,token.text.length);
                                    token.value = uint(parseInt(bin,2));
                                }

                            }
                            //16進
                            else if(token.text.charAt(1)=="x" || token.text.charAt(1)=="X"){//
                                a = token.text.match(/[^0-9a-fA-F]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = OTHER;
                                else{
                                    token.tag += "hex\n";
                                    token.value = uint(parseInt(token.text,16));
                                }
                            }
                            //8進
                            else if(token.text.charAt(1)=="o" || token.text.charAt(1)=="O"){
                                a = token.text.match(/[^0-7]/mg);
                                if(a.length != 1 || token.text.length<3)token.type = OTHER;
                                else{
                                    token.tag += "oct\n";
                                    var oct:String = token.text.substring(2,token.text.length);
                                    token.value = uint(parseInt(oct,8));
                                }
                            }
                            else{
                                //8進
                                a = token.text.match(/[^0-7]/mg);
                                if(a.length != 0 || token.text.length<2)token.type = OTHER;
                                else{//
                                    token.tag += "oct\n";
                                    token.value = uint(parseInt(token.text,8));
                                }
                            }                            
                        }
                        else{//
                            token.type = OTHER;
                        }
                    }
                }
    }//function
    
    public function getBlock(s:uint):Array{
        if(s>scopeEntry.length-1)return null;
        var result:Array = new Array();
        var entry:uint = scopeEntry[s].entry;
        var exit:uint = scopeEntry[s].exit;
        for(var i:int=entry;i<exit+1;i++){
            result.push(list[i]);
        }
        return result;

    }

    
    
    private var scopeEntry:Array;//listからスコープの開始位置を得る
    public function setBlock():Array{
        const err1:String = "scopeError1\n";//スコープの終了がない
        const err3:String = "scopeError2\n";//スコープの開始がない
        const type:String = "block";
        var obj:Object;
        var stac:Array = new Array();
        scopeEntry = null;
        scopeEntry = new Array();//スコープの開始位置のトークンID列
        obj = new Object();
        obj.entry = 0;
        obj.exit = list.length-1;
        scopeEntry.push(obj);//最上位登録
        
        for(var i:int=0;i<list.length;i++){
            if(list[i].type != "mark")continue;//記号以外はスルー
// { }
            if(list[i].text=='{'){
                stac.push(i);
                continue;
            }
            else if(list[i].text=='}'){
                if(stac.length==0){
                    list[i].tag += err3;//エラー
                    continue;
                }
                
                //ペア登録
                obj = new Object();
                obj.entry = stac.pop();
                obj.exit = i;
                scopeEntry.push(obj);
                list[i].type=type;
                list[obj.entry].type =type;
                continue;
            }
                  
        }//for

        if(stac.length!=0){//スコープが閉じられる前に最期まで到達した時
            for(var j:int=0;j<stac.length;j++){
                list[stac[j]].tag += err1;
            }
        }
        return scopeEntry;
    }
    
//-------------------------------       
}//class

Forked