【问题标题】:Automatic Semicolon Insertion in JavaScript without parsing [closed]在不解析的情况下在 JavaScript 中自动插入分号 [关闭]
【发布时间】:2013-02-10 16:53:16
【问题描述】:

我正在编写一个 JavaScript 预处理器,它会在需要的地方自动插入分号。不要问为什么。

现在我知道解决这个问题的一般方法是编写一个 JavaScript 解析器,并根据规范中的 rules 在必要时添加分号。但是我不想这样做,原因如下:

  1. 我不想编写一个成熟的解析器。
  2. 我想保留 cmets 和空格。

我已经(正确地)使用简单的扫描器实现了自动分号插入的第二条和第三条规则。

但事实证明,第一条规则实施起来更具挑战性。所以我有三个问题:

  1. 是否可以使用具有前瞻和后瞻功能的简单扫描器来实施第一条规则?
  2. 如果可能,那么有人已经做到了吗?
  3. 如果没有,我应该如何解决这个问题?

为了完整起见,这里是三个规则:

  • 当从左到右解析程序时,遇到任何语法生成都不允许的标记(称为违规标记),然后自动在前面插入分号如果以下一个或多个条件为真,则违规令牌:

    1. 违规标记与前一个标记至少由一个 LineTerminator 分隔。

    2. 违规令牌是}

  • 当程序从左到右解析时,遇到输入令牌流的结尾,解析器无法将输入令牌流解析为单个完整的 ECMAScript 程序 em>,然后在输入流的末尾自动插入一个分号。

  • 当程序从左到右解析时,遇到某个语法产生式允许的记号,但产生式是受限产生式,并且记号会是紧跟在受限产生式中的注释“[no LineTerminator here]”之后的终端或非终端的第一个令牌(因此这样的令牌称为受限令牌),并且受限令牌是分开的距离上一个标记至少一个 LineTerminator,然后在受限标记之前自动插入一个分号。

但是,前面的规则还有一个额外的覆盖条件:如果分号随后将被解析为空语句,或者该分号将成为 for 声明(12.6.3 部分)。

【问题讨论】:

  • 是的,我要问...为什么要实现一个预处理器来完成 JS 引擎已经为你做的事情?
  • 您应该使用当前版本的规范,请参阅ecma-international.org/ecma-262/5.1es5.github.com
  • @thesystem - 为了好玩。
  • @AaditMShah:老实说,我想不出比这更好的答案了。任何其他目的似乎都是徒劳的。
  • @Bergi - 目测自动分号插入的规则没有改变。

标签: javascript parsing preprocessor automatic-semicolon-insertion


【解决方案1】:

仅使用扫描仪(标记器)无法实现您想要的。这是因为要回答“我们这里需要分号吗?”您需要回答“下一个令牌是违规令牌吗?”要回答这个问题,您需要一个 JavaScript 语法,因为违规标记被定义为该语法在此位置不允许的内容。

我在创建所有标记的列表方面取得了一些成功,然后在第二步处理该列表(所以我会有一些上下文)。使用这种方法,您可以通过编写如下代码来修复一些地方:

  • 向后迭代标记(从最后一个开始,朝向文件开头)
  • 如果当前令牌是IFFORWHILEVAR等:
    • 在标记前跳过空格和 cmets
    • 如果当前令牌不是;,则插入一个

这种方法之所以有效,是因为错误不是随机的。人们总是犯同样的错误。大多数情况下,人们会忘记行尾后的;,而在关键字前寻找缺失的; 是找到它们的好方法。

但这种方法只会让你走这么远。如果您必须可靠地找到所有丢失的分号,则必须编写一个 JavaScript 解析器(或重用现有的解析器)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多