flash on 2011-4-24

by h_sakurai
♥0 | Line 117 | Modified 2011-04-25 13:02:06 | MIT License
play

ActionScript3 source code

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

package {
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        public function FlashTest() {
            addChild(dbgtf);
            dbgtf.y = 20;
            tf.width=465;
            tf.text = "rc="+new CompactParser().parse("a=1+(1+2)+ !--2*3*4");
            addChild(tf);
        }
    }
}

import flash.utils.ObjectInput;
import flash.text.*;
var tf:TextField = new TextField();
var dbgtf:TextField = new TextField();
function dbg(s:String):void {
    dbgtf.text = s + "\n" + dbgtf.text;
}

class Atom {
    public var s:String;
    public var position:Position;
    
}

class Pow extends Atom {
    public var op:Object;
    public var l:Object;
    public var r:Object;
    public function Pow(l:Object,op:Object,r:Object) {
        this.op = op;
        this.l = l;
        this.r = r;
    }
    public function toString():String {
        return "Pow("+l+","+op+","+r+")";
    }

}
class Position {
    public function Position(line:int){
        this.line = line;
    }

    public var line:int;
}

class Token extends Atom {
    public function Token(s:String, pos:Position){
        this.s = s;
        this.position = position;
    }
    public function toString():String {
        return s;
    }
}


class CompactParser {
    public var src:String;
    private var line:int;
    private var ptoken:Token;
    private var token:Token;
    private var reg:RegExp = /^[ \n\t]*([0-9]+|[a-zA-Z_][a-zA-Z_0-9]*|[+\-*\/=!()\[\]{}])/;
    private function lex():Token {
        var s:String = "";
        var m:Object = null;
        // todo line
        // pos
        ptoken = token;
        if ((m = src.match(reg)) == null) {
            if(src.match(/^[\r\n ]*$/) != null) {
                token = new Token("",new Position(line));
            } else {
                m = src.match(/^[\r\n ]*(.?)/);
                throw "found not excepted charactor '"+m[1]+"' at line("+line+").";
            }
            
        } else {
            token = new Token(m[1],new Position(line));
            src = src.substr(m[0].length);
        }
        return ptoken;
    }

    public function parse(src:String):Atom {
        this.src = src.replace("\r\n","\n").replace("\r","\n");
        line = 1;
        lex();
        var rc:Atom = exp(0);
        return rc;
    }

    private var parens:Object = {"(":")","{":"}","[":"]"};
    
    private var prefixs:Object = {"-":25,"!":24};
    private var infixs_r:Object = {"=":0};
    private var infixs:Object = {"-":10,"+":10,"*":20,"/":20};

    private function exp(p:int):Atom {
        var t:Atom = lex();
        if(t.s in parens) {
            var p1:Atom = t;
            t = exp(0);
            var p2:Atom = lex();
            if(p2.s != parens[p1.s]) {
                throw "expect is '"+parens[p1.s]+"' but found '"+p2.s+"' at line("+p2.position.line+").";
            }
            t = new Pow(p1,t,p2);
        }

        if(t.s in prefixs && prefixs[t.s] >= p) {
            var op:Atom = t;
            t = new Pow("",op,exp(prefixs[t.s]));
            dbg("t="+t);
        }

        while (true) {
            if(token.s in infixs && infixs[token.s] > p) {
                op = lex();
                t = new Pow(t,op,exp(infixs[op]));
                continue;
            }
            if(token.s in infixs_r && infixs_r[token.s] >= p) {
                op = lex();
                t = new Pow(t,op,exp(infixs_r[op]));
                continue;
            }
            break;
        }
        return t;
    }
}