forked from: forked from: forked from: getToken
forked from forked from: forked from: getToken (diff: 318)
かっこ抽出 {} トークンへのアクセス方法 プロセスライン上の要素へのアクセス 1ステップをString で取得 階層化しているものは省略する private function func():void{ } -> private function func():void; ラインリストからインデックスで指定 原文 FPS計測 Wonderfl.capture(stage); 原文テキスト入力ボックス
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/d6pp
*/
// forked from tepe's forked from: forked from: getToken
// forked from tepe's forked from: getToken
// forked from tepe's getToken
/*
かっこ抽出 {}
トークンへのアクセス方法
プロセスライン上の要素へのアクセス
1ステップをString で取得
階層化しているものは省略する
private function func():void{ } -> private function func():void;
ラインリストからインデックスで指定
*/
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 so : SharedObject;
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;
so = SharedObject.getLocal("data");
if(so){
if(so.data.text != null){
t1.text = so.data.text;
}
else{
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}");
so.data.text = t1.text;
}
}
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:token1;
private var list:Array;
private var stack:Array;
private function onChange(e:Event=null):void{
list = new Array();
stack = new Array();
tk = new token1();
stack.push(new Array());
var i:int;
var index:int=0;
var len:int = t1.length;
var lineList:Array = new Array();
var stack2:Array = new Array();
var bufStr:String = new String();
so.data.text = t1.text;
tk.createToken(t1.text);
//var cnt:int=0;
//t2.text = "";
stack[stack.length-1].push(0);//ステップカウント
stack2.push(tk.getToken(0));
for(i=0;i<tk.length;i++){
var obj:Token = tk.getToken(i);
if(obj == null)bufStr += "obj == null\n";
//記号の処理
if(obj.type == Token.MARK){
var s:String = obj.text;//tk.getString(i);
var index2:int = i;
if(s == ";"){
stack[stack.length-1].push(index2);//ステップカウント
}
else if(s=="{"){
stack.push(new Array());
stack2.push(tk.getToken(i));
stack[stack.length-1].push(index2);//スコープ開始
}
else if(s=="}"){
var scope:Scope = new Scope();
var slen:int = scope.setScope(stack2.pop(),obj);
bufStr += "slen="+slen.toString()+" i="+i.toString()+" objId="+obj.createId.toString();
bufStr += " start="+scope.start.createId.toString()+" end="+scope.end.createId.toString()+"\n";
bufStr += scope.getString+"\n\n";
lineList.push(scope);
stack[stack.length-1].push(index2);//スコープ終了
list.push(stack.pop());
stack[stack.length-1].push(index2);//ステップカウント
}
}
}//for
stack[stack.length-1].push(tk.length);//ステップカウント
list.push(stack.pop());//ルート
for(i=0;i<list.length;i++){
bufStr += "line"+(i+1)+": ";//list[i].length.toString()+"\n";
var ar:Array = list[i];
for(var j:int=0;j<ar.length;j++){
bufStr += ar[j].toString()+" ";
}
bufStr += "\n";
}
t2.text = bufStr;
}
}
}
class NodeObject{
private static var createCnt:int;
private var _id:int;
private var _parent:NodeObject;
private var _children:Array;
public function NodeObject(){
_id = createCnt;
createCnt++;
_children = new Array();
}
private function set parent(obj:NodeObject):void{
_parent = obj;
}
public function get id():int{
return _id;
}
public function get length():int{
return _children.length;
}
public function addChild(obj:NodeObject):int{
obj.parent = this;
_children.push(obj);
return _children.length;
}
}
//トークンオブジェクト
class Token{
private static var idCnt:int;
private var tokenId:int;
public var text:String;//文字列
public var type:int;//タイプ
//public var lineNum:int;//属するプロセスライン
//トークンの並びを保持する
public var next:Token;
public var prev:Token;
public var parent:Token;
public var child:Token;
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 static const SCOPE:int = 7;//スコープの置き換え
public function Token(){
idCnt++;
tokenId = idCnt;
}
public function get createId():int{
return tokenId;
}
}
//開始位置と終了位置をトークンインデックスで保持する
//所属するスコープ
//スコープ全体のString表現:下位スコープを省略するか?そのまま展開するか?
class Scope{
private static var idCnt:int;
private var scopeId:int;//識別値
private var _start:Token;//開始位置のトークン
private var _end:Token;//終了位置のトークン
public var parenat:Token;//上位スコープ
private var _length:int;
//開始位置と終了位置の設定
//スコープチェーンの設定
//スコープに含まれる下位スコープ
public function Scope(){
idCnt++;
scopeId = idCnt;
}
public function get createId():int{
return scopeId;
}
public function get length():int{
return _length;
}
public function get start():Token{
return _start;
}
public function get end():Token{
return _end;
}
public function get getString():String{
var str:String = new String();
var t:Token = _start;
while(t.next != null){
str += t.text;
if(t.createId == _end.createId)break;
t = t.next;
}
return str;
}
public function get getString2():String{
var str:String = new String();
var t:Token = _start;
while(t.next != null){
break;
str += t.text;
if(t.createId == _end.createId)break;
t = t.next;
}
return str;
}
public function setScope(entry:Token,exit:Token):int{
if(entry.text != "{")return -1;
if(exit.text != "}")return -2;
_start = entry;
_end = exit;
_length = 0;
var t:Token = entry;
while(true){
_length++;
if(t.next == null)break;
else if(t.createId == exit.createId)break;
t = t.next;
}
return _length;
}
}
//1ステップに含まれるトークンへの参照
//ステップが所属するスコープ
//ステップのString表現
class Step{
private static var idCnt:int;
private var stepId:int;//ステップの識別値
public var start:int;
public var end:int;
public var parentID:int;//所属スコープ
private var tokenList:Array;
public function Step(){
idCnt++;
stepId = idCnt;
tokenList = new Array();
}
public function get createId():int{
return stepId;
}
//トークン取得
public function getToken(index:int):Token{
if(tokenList == null)return null;
if(0 <= index && index < tokenList.length)return tokenList[index];
return null;
}
public function addToken(token:Token):void{
tokenList.push(token);
}
public function get length():int{
return tokenList.length;
}
}
//要素
class Keyword{
private static var idCnt:int;
private var id:int;
private var text:String;
private var type:int;
private var parentId:int;//所属スコープ
public function Keyword(){
idCnt++;
id = idCnt;
}
}
//////////////////////////////////////////////////////////////////////////
// トークン列取得
//////////////////////////////////////////////////////////////////////////
//テキストからトークンを抽出する
class token1{
private var tokenList:Array;
private var _length:int;
private var source:String;
public function token1(){
}
//指定インデクスからmax個までトークン抽出
//抽出したトークンはlistに追加
//抽出したところまでのインデクスを返す
public function createToken(str:String):int{
source = str;
tokenList = new Array();
index01 = 0;
var i:int = 0;
//func01();return _length;
while(i<str.length){
i = func01();
}
_length = tokenList.length;
return _length;
}
public function get length():int{
return _length;
}
//先頭からの順を指定してトークンを取得
public function getToken(index:int):Token{
if(index<0 && tokenList.length<=index)return null;
return tokenList[index];
}
//トークン列に追加
private function addToken(str:String,type:int):int{
var obj:Token = new Token();
obj.text = str;
obj.type = type;
obj.next = null;
tokenList.push(obj);
if(1<tokenList.length){
tokenList[tokenList.length-1].prev = tokenList[tokenList.length-2];
tokenList[tokenList.length-2].next = tokenList[tokenList.length-1];
}
else tokenList[tokenList.length-1].prev = null;
return tokenList.length;
}
//-------------------------------------------------------------
//開始インデクスを受け取りトークンのタイプを返す
private var index01:int=0;
private function func01():int{//
if(index01 >= source.length)return source.length;
var index:int = index01;
var type:int;//トークンタイプ
var str:String;//トークン文字列
var reg:RegExp = new RegExp();
var result:Object;
//トークンタイプ:空白か?
if( source.charAt(index)== " " ||
source.charAt(index)=="\t" ||
source.charAt(index)=="\n" ||
source.charAt(index)=="\r" ){
type = Token.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 = Token.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 = Token.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 = Token.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 = Token.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 = Token.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 = Token.COMMENT;
if(result == null){//エラー
type = Token.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 = Token.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 = Token.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 = Token.MARK;
str = source.charAt(index);
index01 = index+1;
addToken(str,type);
return index01;
}
//その他文字列 マルチバイト文字等はここに入る
type = Token.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