Code Monkey home page Code Monkey logo

Comments (17)

RubyLouvre avatar RubyLouvre commented on June 8, 2024
function anonymous(vm0) {
'use strict';
var test2 = vm0.test2, test1 = vm0.test1
return test1 && test2
}



function anonymous(vm0) {
'use strict';
var test1 = vm0.test1, test2 = vm0.test2
return test2 && test1
}



function anonymous(vm0) {
'use strict';
var test1 = vm0.test1, test2 = vm0.test2
return test2 || test1
}

这是新parser生成的求值函数

function anonymous(test1372575919386) {
with(test1372575919386){
var ret1372575919386 = test1 && test2
}

return ret1372575919386
}


function anonymous(test1372575919387) {
with(test1372575919387){
var ret1372575919387 = test2 && test1
}

return ret1372575919387
}


function anonymous(test1372575919389) {
with(test1372575919389){
var ret1372575919389 = test2 || test1
}

return ret1372575919389
}

这是旧parser生成的求值函数

from avalon.

yxnino avatar yxnino commented on June 8, 2024
var rule = item.rule;
var names = rule.replace(/["|']\w*["|']/g, ' ').match(/\w+/g); // 先replace掉字符串,匹配到的变量名赋给names

/*去掉重复的项和JS关键字*/
var unique = {};
names = dojo.filter(names, function(name) {
    if (!unique[name]) {
        unique[name] = true;
        return dojo.indexOf(smartdot.Validator.keyword, name) === -1;
    } else {
        return false;
    }
});

var param = [];
var arg = [];
dojo.forEach(names, function(name) {
    if (name in smartdot.Validator.cache.index) {
        param.push(smartdot.Validator.cache.get(name).get('value'));
        arg.push(name);
    }
});

return item.lambda('(' + arg.join(', ') + ') => (' + item.rule + ')').apply(item, param);

跟我之前做的一个小功能思路一样

from avalon.

Gaubee avatar Gaubee commented on June 8, 2024

这里可以帮你省下几个字符。

按你的需求来说,是要提取类似全局变量的变量名,除了eval之类的使用字符串生产变量的东西。
所以,在遇到那些关键字,直接用try、catch来走一边并缓存成相应的hash表,就可以了,并不会影响性能,毕竟缓存了。

贴上地址:https://gist.github.com/Gaubee/5938254

因为有用到循环,所以顺便把你getValueFunction里面那个filter写在一起。

from avalon.

Gaubee avatar Gaubee commented on June 8, 2024

另外细看你的正则,有坑:单双引号的字符串匹配竟然就这样写:'[^']*'|"[^"]*"
遇到"nihao"dajiahao"就出问题了。

比如

"nihao\"dajiahao"  ; test1&&test2;"nihao\"dajiahao" 

中间那部分就直接被过滤掉了……

DoubleQuotedString = new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g');//双引号字符串
SingleQuotedString = new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'",'g');//单引号字符串

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024

abcd 搞出的抽取变量的函数,我做了部分调整

            var rword = /[^, ]+/g
            function oneObject(array, val) {
                if (typeof array === "string") {
                    array = array.match(rword) || []
                }
                var result = {},
                        value = val !== void 0 ? val : 1
                for (var i = 0, n = array.length; i < n; i++) {
                    result[array[i]] = value
                }
                return result
            }
            function getVars(s) {
                var s_kws = " break case catch continue default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with null true false"
                        + " abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile ";

                var keywords = oneObject(s_kws)
                var re_ws = /\s+/;
                var re_comm = /\/\/[^\r\n\u2028\u2029]*|\/\*(?:\/|\**[^*/])*\*+\//;
                var re_id = /[a-zA-Z_$][\w$]*/;
                var re_punc = /~|\}|\|\||\|=|\||\{|\^=|\^|\]|\[|\?|>>>=|>>>|>>=|>>|>=|>|===|==|=|<=|<<=|<<|<|;|:|\.|-=|--|-|,|\+=|\+\+|\+|\*=|\*|\)|\(|&=|&&|&|%=|%|!==|!=|!|\/=?/;
                var re_num = /0x[\dA-Fa-f]+|(?:(?:0|[1-9]\d*)(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
                var re_str = /"(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*'/;

                var re = function(a) {
                    for (var i = 0; i < a.length; ++i)
                        a[i] = '(' + a[i].source + ')';
                    return RegExp(a.join('|') + '|', 'g');
                }([re_ws, re_comm, re_id, re_punc, re_num, re_str]);

                var beforeIsDot = false;
                var r = [];
                var t;

                function f(all, ws, comm, id, punc, num, str) {
                    if (beforeIsDot) {
                        beforeIsDot = false;
                    }
                    else {
                        if (all == '.') {
                            beforeIsDot = true;
                        }
                        else {
                            if (id && !keywords[id])
                                r.push(id);
                        }
                    }
                }
                while (t = re.exec(s)) {
                    if (!t[0]) {
                        if (t.index != s.length)
                            throw Error("error: " + t.index);
                        break;
                    }
                    f.apply(null, t);
                }

                return r;
            }
            console.log(getVars("new Date()"))

from avalon.

Gaubee avatar Gaubee commented on June 8, 2024

@RubyLouvre 这种写法说实话,很不稳定,而且可读性又低,你让getVars解析一下getVars自己。

自己做一下测试就知道,我用之前从你那边修改的Gist(这个还是用上eval的低效)和这个新的做比较,对getVariables这个函数体进行解析,不论从 速度可读性稳定性 上都比你后来贴上来的这段代码好多了。

附上测试地址:https://gist.github.com/Gaubee/5945554

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024

那个注释正则,可以简化一下
var re_comm = ///[^\r\n\u2028\u2029]|/_[\s\S]?_//;

这样也更快一点
其中的 \u2028\u2029 也可以去掉
因为一般代码中不会出现这种字符

from avalon.

Gaubee avatar Gaubee commented on June 8, 2024

@RubyLouvre 你可以运行一下你自己自己写的那段代码,相比abcd写的,特别是遇上简单结构的,速度优势更加明显,因为代码结构上的优势。

你也可以运行一下我上面贴给你的测试代码。

总之我觉得还是用你之前自己写的那段比较好。abcd这代码明显是用在更复杂的分析,而你的代码只是用于变量的提取。

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024

我现在不想用with了
比如说我的绑定属性里面有个items
而这个绑定属性在select元素上
如果用with, 它就找到元素的select属性,而不是VM的items属性,这真吐血

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024

我早期想到的怪招,利用TypeError进行抽取

    //将绑定属性的值或插值表达式里面部分转换一个函数compileFn,里面或包含ViewModel的某些属性
    //而它们分分种都是setter, getter,成为双向绑定链的一部分
    var regEscape = /([-.*+?^${}()|[\]\/\\])/g;

    function escapeRegExp(target) {
        //将字符串安全格式化为正则表达式的源码
        return target.replace(regEscape, "\\$1");
    }
    var isStrict = (function() {
        return !this;
    })();

    function insertScopeNameBeforeVariableName(e, text, scopeList, names, args, random) {
        var ok = false;
        if (window.dispatchEvent) { //判定是否IE9-11或者为标准浏览器
            ok = e instanceof ReferenceError;
        } else {
            ok = e instanceof TypeError;
        }
        //opera9.61
        //message: Statement on line 810: Undefined variable: nickName
        //opera12
        //Undefined variable: nickName
        //safari 5
        //Can't find variable: nickName
        //firefox3-20  chrome
        //ReferenceError: nickName is not defined
        //IE10
        //“nickName”未定义 
        //IE6 
        //'eee' 未定义 
        if (ok) {
            if (window.opera) {
                var varName = e.message.split("Undefined variable: ")[1];
            } else {
                varName = e.message.replace("Can't find variable: ", "")
                        .replace("“", "").replace("'", "");
            }
            varName = (varName.match(/^[\w$]+/) || [""])[0]; //取得未定义的变量名
            for (var i = 0, scope; scope = scopeList[i++]; ) {
                if (scope.hasOwnProperty(varName)) {
                    var scopeName = scope.$id + random;
                    if (names.indexOf(scopeName) === -1) {
                        names.push(scopeName);
                        args.push(scope);
                    }
                    //这里实际还要做更严格的处理
                    var reg = new RegExp("(^|[^\\w\\u00c0-\\uFFFF_])(" + escapeRegExp(varName) + ")($|[^\\w\\u00c0-\\uFFFF_])", "g");
                    return text.replace(reg, function(a, b, c, d) {
                        return b + scopeName + "." + c + d; //添加作用域
                    });
                }
            }

        }
    }
    var doubleQuotedString = /"([^\\"\n]|\\.)*"/g;
    var singleQuotedString = /'([^\\'\n]|\\.)*'/g;

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024

取自我早期的avalon https://github.com/RubyLouvre/mass-Framework/blob/1.4/avalon.js#L1166

from avalon.

aui avatar aui commented on June 8, 2024

@RubyLouvre 过滤算法有更新,1、完善数字判断,避免BUG 2、完善字符串正则:

aui/art-template#27

欢迎共同完善

from avalon.

limodou avatar limodou commented on June 8, 2024

做广告?

from avalon.

aui avatar aui commented on June 8, 2024

@limodou 楼主采用了我写的parser,他不知道有在BUG,我修复后再告诉他--这何来广告一说?

from avalon.

limodou avatar limodou commented on June 8, 2024

报歉,不知道前因后果。

from avalon.

yolio2003 avatar yolio2003 commented on June 8, 2024

原来几大高手一起合作在弄, 太赞了

from avalon.

RubyLouvre avatar RubyLouvre commented on June 8, 2024
 var str = "aaa.bbb.ccc+ddd"
            var str = "aaa[bbb].ccc-888+ikk"
            var str = "aaa[ bbb ].ccc-888+ikk"
            var str = "aaa['bbb'].ccc||a888&&ikk(ddd.eee)"
            var str = 'aaa["aaa"]+null'
            //取得变量名或属性名

            var KEYWORDS =
                    // 关键字
                    'break,case,catch,continue,debugger,default,delete,do,else,false'
                    + ',finally,for,function,if,in,instanceof,new,null,return,switch,this'
                    + ',throw,true,try,typeof,var,void,while,with'

                    // 保留字
                    + ',abstract,boolean,byte,char,class,const,double,enum,export,extends'
                    + ',final,float,goto,implements,import,int,interface,long,native'
                    + ',package,private,protected,public,short,static,super,synchronized'
                    + ',throws,transient,volatile'

                    // ECMA 5 - use strict
                    + ',arguments,let,yield'

                    + ',undefined';
            function oneObject(array, val) {
                if (typeof array === "string") {
                    array = array.match(/[^, ]+/g) || []
                }
                var result = {},
                        value = val !== void 0 ? val : 1
                for (var i = 0, n = array.length; i < n; i++) {
                    result[array[i]] = value
                }
                return result
            }
            var keywordOne = oneObject(KEYWORDS)
            var rvar = /\b[\$\_a-z][\w$]*(?:\.[$\w]+|\[[^\]]+\])*/ig

            var rstringLiterals = /(['"])(\\\1|.)+?\1/g
            var rregexp = /([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g
            var rcomment1 = /\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g
            var rcomment2 = /\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g
            function getVars(str) {
//http://james.padolsey.com/javascript/javascript-comment-removal-revisted/
                var uid = '_' + +new Date(),
                        primatives = [],
                        primIndex = 0;
                str = str
                        /* 移除所有字符串*/
                        .replace(rstringLiterals, function(match) {
                            primatives[primIndex] = match;
                            return (uid + '') + primIndex++;
                        })

                        /* 移除所有正则 */
                        .replace(rregexp, function(match, $1, $2) {
                            primatives[primIndex] = $2;
                            return $1 + (uid + '') + primIndex++;
                        })

                        .replace(rcomment1, "")

                        .replace(rcomment2, "")


                        .replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), "")


                var vars = []

                str.replace(rvar, function(a) {
                    if (keywordOne[a])
                        return
                    vars.push(a.replace(RegExp(uid + '(\\d+)', 'g'), function(match, n) {
                        return primatives[n];
                    }))
                })
                console.log(vars)

            }

            getVars(str)

from avalon.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.