首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >需要regex来完成语言解析器的基本递归特性(或帮助开发Babel插件)

需要regex来完成语言解析器的基本递归特性(或帮助开发Babel插件)
EN

Stack Overflow用户
提问于 2015-12-05 01:11:28
回答 1查看 131关注 0票数 1

我有以下命令:

代码语言:javascript
运行
复制
/(?:this\.(\w+)\(([\s\S]*?)\))/g

它用于接受如下代码:

代码语言:javascript
运行
复制
this.doSomething(foo, bar)

并将其替换为:

代码语言:javascript
运行
复制
this.lookup('doSomething', [foo, bar])

对于该用例(最常见的用例),它正确工作,但如果在用例中使用this,则不能工作:

代码语言:javascript
运行
复制
this.doSomething(foo, bar, this.baz())

其结果是错误的:

代码语言:javascript
运行
复制
this.lookup('doSomething', [foo, bar, this.baz(]))

应该是这样:

代码语言:javascript
运行
复制
this.lookup('doSomething', [foo, bar, this.baz()])

这是第一个问题。它实际上应该像this.doSomething一样被转换,所以最终的结果应该是:

代码语言:javascript
运行
复制
this.lookup('doSomething', [foo, bar, this.lookup('baz', [])]);

基本上,我的regex假设来自this.baz()的结束括号是this.doSomething()的结束括号,并且也不递归地操作。这里我需要某种递归行为/控制。

我听说过xregexp,但我不知道它如何帮助我。它似乎也是真正的语言解析器可能是唯一的方法。我在那里经验不多,但我不怕弄脏我的手。像Esprima这样的工具能帮上忙吗?

最后,我希望在代码的构建步骤中做一些小的语言/语法更改,也就是完全像Babel那样。事实上我在利用巴贝尔。也许某种Babel插件是一种选择?

无论如何,我对quickfix技巧或更支持/健壮的语言解析技术都持开放态度。我也很好奇,这些问题通常是如何处理的。扫描整个输入和匹配的打开/关闭大括号/括号/等等,我想?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-05 19:32:53

下面是一个例子,说明如何使用Babel插件来完成这个任务:

代码语言:javascript
运行
复制
var names = ['doSomething', 'baz'];

module.exports = function(context){
    var t = context.types;

    return {
        visitor: {
            CallExpression: function(path){
                var callee = path.get('callee');
                // Only process "this.*()" calls.
                if (!callee.isMemberExpression() ||
                    !callee.get('object').isThisExpression() ||
                    !callee.get('property').isIdentifier()) return;

                // Make sure the call is to one of your specific functions.
                if (names.indexOf(path.node.callee.property.name) === -1) return;

                // Build "this.lookup('<name>', [])".
                path.replaceWith(t.callExpression(
                    t.memberExpression(t.thisExpression(), t.identifier('lookup')),
                    [
                        t.stringLiteral(path.node.callee.property.name),
                        t.arrayExpression(path.node.arguments),
                    ]
                ));
            }
        }
    };
}

例如,如果将其放到plugin.js函数中,则可以创建一个.babelrc配置文件,并确保./plugin.js或指向它的任何路径都在plugins数组中。

.babelrc

代码语言:javascript
运行
复制
{
  "presets": ['es2015'],
  "plugins": ['./plugin']
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34100079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档