flash on 2012-6-12
♥0 |
Line 464 |
Modified 2012-06-13 07:53:52 |
MIT License
archived:2017-03-30 02:52:45
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