ECMA标准的各种解析器。

calmjs.parse的Python项目详细描述


calmjs.parse

用于理解的解析器和助手库的集合 ecmascript;一个近乎功能完整的fork of slimit 。cli前端 对于此软件包,将作为 压接 单独发货。 https://travis-ci.org/calmjs/calmjs.parse.svg?branch=1.2.0https://ci.appveyor.com/api/projects/status/5dj8dnu9gmj02msu/branch/1.2.0?svg=truehttps://coveralls.io/repos/github/calmjs/calmjs.parse/badge.svg?branch=1.2.0

简介

对于任何使用javascript代码的构建系统 结合模块系统,能够理解哪些模块 一组给定的资源要求或提供是最重要的。作为卡尔姆一家 project提供了一个生成和使用这些模块的框架 定义,全面理解 给定的javascript源是给定的。这个目标最初是实现的 使用一个javascript minifier库,它还提供了 使用python lex yacc(即 )。

然而,截至2017年年中,有人注意到 slimit 仍在 四年以上的最低维护状态(最近 版本0.8.1于2013年3月26日发布,同时发布了一些严重的 悬而未决的问题在这段时间内一直没有得到解决。 在那段时间里。由于calmjs框架的开发需要 这些问题要尽快纠正,决定 slimit的解析器部分被制作出来。这是为了迎合 当前对calmjs项目的兴趣在那个时刻及时出现。

叉子最初是从另一个纤细的叉子上切下来的(特别是 lelit/slimit ),正如它介绍的那样 聚合了来自不同来源的许多错误修复。确保一 更好的质量控制和保证,一些有问题的变化 那个叉子引来的东西被移走了。此外,还创建了新的测试来 使覆盖率达到最大,在 slimit 跟踪器上报告的问题是 在适用的情况下,记录并正式化为测试用例。最后,语法 已更新规则以确保更好地符合ECMA-262(ES5) 规格。

calmjs.parse的目标是提供一个与slimit类似的api 提供,除了以更具扩展性的方式 正确性检查到位。然而,这导致了一些操作 这可能需要比slimit实现的时间更长,例如 输出打印效果良好。

通过 压接

安装

可以执行以下命令来获取最新的稳定 从pypi安装到 当前的python环境。

$ pip install calmjs.parse

由于此包使用 ply ,因此需要生成优化 它的lexer模块。calmjs.parse的轮分布 不需要这个额外的步骤,因为它包含这些预生成的模块 对于3.11版之前的 ply (当时提供的最新版本 但是源tarball或如果 ply 版本 安装在受支持版本之外,如下所示 注意事项适用。

如果最近发布的 ply 可用,并且环境 升级到那个版本,那些预先生成的模块可能会 不兼容,这可能导致性能下降和/或错误。 可以通过手动优化来实现纠正措施 如果新版本的 calmjs.parse 不可用,或者 ply 可能 如果可能,请降级回3.11版。

安装软件包后,可以对安装进行测试 直接使用

替代安装方法(针对开发人员、高级用户)

目前仍在开发calmjs.parse 功能和错误修复,开发版本可以通过 吉特喜欢这样:

$ pip install git+https://github.com/calmjs/calmjs.parse.git#egg=calmjs.parse

或者,可以直接克隆git存储库并执行 python setup.py在源代码的根目录中开发 目录。

可能需要对平台和 不使用utf8作为默认编码的系统。

手动优化

由于lex和yacc需要生成符号表,因此 优化性能就是缓存结果。对于 ,这是 使用自动生成的模块完成。但是,生成的文件是 用版本号标记,因为结果可能特定于 已安装版本的 。在calmjs.parse中 它们是特定于 ply 和主要python版本的名称 版本,因为两者都会导致 自动生成模块的输出和期望。

通常,此优化过程是自动的,并且是正确的 将生成符号表,但在某些情况下 失败,因此为此原因 calmjs.parse 提供一个helper模块 可选择调用以确保 编码用于生成该文件。其他可能的原因 必须允许系统管理员这样做 用户,因为他们可能没有该级别的写入权限。

要从shell执行优化器,提供的帮助程序脚本可以 像这样使用:

$ python -m calmjs.parse.parsers.optimize

如果出现警告,警告令牌已定义但未使用,则它们 可能会被安全地忽略。

此步骤通常对于安装此软件包的用户是可选的 从pypi通过python轮,提供了 安装部分已处理。

测试安装

为了确保 calmjs.parse 安装正常工作, 内置测试套件可以通过以下方式执行:

$ python -m unittest calmjs.parse.tests.make_suite

如果出现故障,请在问题跟踪程序中提交一个问题 回溯,和/或方法of安装。请也包括 有关环境的适用信息,例如 这个软件,python版本,操作系统环境 已安装的 ply 版本,以及与 手头的问题。

用法

由于这是一个解析器库,因此不提供可执行的shell命令。 但是,在顶层提供了一个helper可调用对象 立即访问解析功能。可以这样使用:

>>> fromcalmjs.parseimportes5>>> program_source=u'''
... // simple program
... var main = function(greet) {
...     var hello = "hello " + greet;
...     return hello;
... };
... console.log(main('world'));
... '''>>> program=es5(program_source)>>> # for a simple repr-like nested view of the ast>>> program# equivalent to repr(program)<ES5Program @3:1 ?children=[
  <VarStatement @3:1 ?children=[
    <VarDecl @3:5 identifier=<Identifier ...>, initializer=<FuncExpr ...>>
  ]>,
  <ExprStatement @7:1 expr=<FunctionCall @7:1 args=<Arguments ...>,
    identifier=<DotAccessor ...>>>
]>
>>> # automatic reconstruction of ast into source, without having to>>> # call something like `.to_ecma()`>>> print(program)# equivalent to str(program)var main = function(greet) {
  var hello = "hello " + greet;
  return hello;
};
console.log(main('world'));

>>>

请注意缩进的变化,因为默认打印机有自己的缩进 缩进方案。如果需要注释,可以调用解析器 将 与u comments=true一起使用

>>> program_wc=es5(program_source,with_comments=True)>>> print(program_wc)// simple program
var main = function(greet) {
  var hello = "hello " + greet;
  return hello;
};
console.log(main('world'));

>>>

还需要注意的是,捕获注释有一些限制 记录在限制部分。

解析器类在calmjs.parse.parsers下组织。 模块,每种语言都在各自的模块下。一 在 calmjs.parse.lexers 模块。目前,只有ES5支持 实施。

精美/微型打印

还有一组漂亮的打印辅助程序,用于将ast返回 变成一根绳子。它们可用作函数或类构造函数, 并通过组合在 calmjs.parse.unparsers和相关模块。

有一个默认的短手助手,用于旋转先前生成的 AST返回到字符串中,可以使用 参数,例如用于缩进的字符:(注意 通过打印隐式调用 以前是通过这个实现的。

>>> fromcalmjs.parse.unparsers.es5importpretty_print>>> print(pretty_print(program,indent_str='    '))var main = function(greet) {
    var hello = "hello " + greet;
    return hello;
};
console.log(main('world'));

>>>

也有一个打印没有任何不需要的空白,作品 作为源代码缩小器:

>>> fromcalmjs.parse.unparsers.es5importminify_print>>> print(minify_print(program))var main=function(greet){var hello="hello "+greet;return hello;};...
>>> print(minify_print(program,obfuscate=True,obfuscate_globals=True))var a=function(b){var a="hello "+b;return a;};console.log(a('world'));

注意,在第二个示例中, obfuscate_globals 选项是 仅用于演示全局范围上的源代码混淆, 而且这通常不是一个应该在生产上启用的选项 打算由其他包(其他源)重用的库代码 引用原始未模糊的名称将无法执行此操作。

或者,可以使用 以与上述基本对象相同的名称提供的属性 最初是导入的。相关关键字参数将被转移 到相应的底层函数,例如:

>>> # pretty print without comments being parsed>>> print(es5.pretty_print(program_source))var main = function(greet) {
  var hello = "hello " + greet;
  return hello;
};
console.log(main('world'));

>>> # pretty print with comments parsed>>> print(es5.pretty_print(program_source,with_comments=True))// simple program
var main = function(greet) {
  var hello = "hello " + greet;
  return hello;
};
console.log(main('world'));

>>> # minify print>>> print(es5.minify_print(program_source,obfuscate=True))var main=function(b){var a="hello "+b;return a;};console.log(main('world'));

源映射生成

对于源映射的生成,较低级别的unparser实例可以 通过打印机工厂功能之一构造。经过 在ast节点中,将生成生成包含 生成的文本片段,以及其他有助于 生成源映射。有来自 可以像这样使用calmjs.parse.sourcemap模块来编写 将源代码重新生成到某个流,同时处理 结果转换为源映射文件。例如:

$ pip install calmjs.parse
0

同样,这对minify打印机也同样有效,它提供 使用不需要的空白创建缩小的输出的能力 删除并用尽可能短的值模糊标识符。

注意,在前面的例子中,write中的第二个返回值 方法未使用,并且传入了自定义值。这是 只是因为 程序是如何从字符串生成的,因此 sourcepath属性没有为 在生成的源映射中填充 "sources" 列表。对于 下面的示例为程序上的该属性指定一个值 直接。

$ pip install calmjs.parse
1

用于处理命名的treams(即打开的文件,或 流对象,如分配有name属性的 io.stringio io 模块的 read write 函数提供。 下面的示例演示如何使用函数从 流式处理并将相关项写回write only 溪流:

$ pip install calmjs.parse
2

用于将多个源简单地连接到一个文件中,以及 内联源映射(即,其中sourcemappingurl是 json字符串的base64编码),可以执行以下操作:

$ pip install calmjs.parse
3

在本例中, io.write 函数提供了 unparser,一个生成器表达式,它将从 两个源文件,然后是target和sourcemap参数 是相同的,它强制源映射生成器生成 Base64编码。

请注意,如果向小型打印机提供多个AST, 全局变量被混淆后,生成的脚本将具有 当解组完成时,被后面的全局名称弄乱的全局名称 分别通过 io.write 函数。

高级用法

低级拆开API

当然,前面演示的打印机是使用 底层的unparser类,它反过来连接了walk 在Walker模块中找到的函数和Dispatcher类。步行 函数使用Dispatcher的一个实例遍历AST节点 类,它为特定的 提供的ast节点的类型,以及相关的处理程序。这些 可以使用现有的规则提供程序函数设置处理程序。为了 例如,一个打印机,用于在维护 es5 ast输出的缩进可以这样构造:

$ pip install calmjs.parse
4

每个规则(函数)都有特定的选项,使用 特定的关键字参数和详细信息分别记录在它们各自的 文档字符串。

树木行走

ast(抽象语法树)泛型walker类在 合适的命名模块calmjs.parse.walkers。两个默认walker 提供类。其中一个是reprwalker类 之前演示过。另一个是walker类 提供AST树的泛型树行走方法的集合 节点。下面是关于如何提取所有 给定脚本文件中的对象分配:

$ pip install calmjs.parse
5

更多细节和示例用法可从 在模块中找到docstrings。

限制

当前的评论可能不完整

由于lexer/parser的实现以及ast 节点类型已经实现,在 如果启用,则可能会公开注释。目前,这种限制是存在的 对于由使用多个 lexer令牌一次-只有在第一个令牌之前的注释将是 已捕获,并丢弃所有剩余评论。

例如,这个限制意味着 else 之前的任何注释 标记将被忽略(因为注释将由 提供,如果 token),作为 的生产规则,如果 节点同时使用这两个 令牌和实现的节点只为 评论。同样,在三元组中 标记之前的任何注释 语句也将被丢弃,因为这是使用的第二个令牌 根据产生 条件节点的产生式规则。

故障排除

语法分析器类的实例化失败,出现unicodeencodeerror

对于未将utf8配置为默认值的平台或系统 编码时,在构造 分析器实例。例如:

$ pip install calmjs.parse
6

提供了一个解决方案帮助程序脚本,其执行方式如下:

$ python -m calmjs.parse.parsers.optimize

有关此主题的更多详细信息,请参见手动优化。 本文档的一节。

慢性能

由于这个程序基本上完全分解成非常小的函数, 与其他方法相比,这将导致严重的性能损失 由于函数调用是最昂贵的 python中的操作。有可能进一步优化 通过组合所有 但是,解析的生成器对每个asttype节点类型都起作用 这可能需要令牌和布局函数都没有 具有名称冲突的参数,新函数将接受 一次就解决了这些争论。

贡献

法律

calmjs.parse包版权所有(c)2017奥克兰生物工程 奥克兰大学研究所。calmjs.parse包是 根据麻省理工学院许可证(特别是外籍人士许可证)进行许可,其中 与slimit软件包发布时使用的许可证相同。

lexer、解析器和其他类型定义部分是 最初从 slimit 包导入; slimit 是版权所有(C) 拉斯兰·斯皮瓦克。

CALMJS项目版权所有(c)2017奥克兰生物工程 奥克兰大学研究所。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java使用Hibernate替换一组记录的正确方法是什么   java调用存储过程时返回相同的记录   java创建一个ActionListener,逐步更新JPanel   java如何为这个WSDL工作wsimport我遇到了错误,我无法让它工作   Java Mysql空指针异常   java执行超时(1600ms)如何优化此代码以更快地运行?   java在Spring的@Transactional方法期间处理异常   java如何在驱动程序类中调用泛型方法   java如何理解SpringMVC工作流?   java在TomcatJSP页面中使用JDK15的JEP378文本块   java为什么在类中找不到主方法?   在java中创建链表而不使用内置方法/importing util   java在空格和破折号上拆分字符串,但不在字符串的值上拆分字符串   不带按钮的java JOptionPane   java如何减少Netbeans中JTable的列?   通过spring的JavaRESTAPI   Java:最简单的日期减法   来自JPanel的java BuffereImage,背景透明   JavaJFrame:如何使用linebreaklike行为创建简单布局?