JavaScript中的自动分号插入,无需解析

时间:2013-02-25 14:04:00

标签: javascript parsing preprocessor automatic-semicolon-insertion

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

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

  1. 我不想写一个完整的解析器。
  2. 我想保留评论和空白。
  3. 我已经(正确地)使用简单的扫描仪实现了自动分号插入的第二和第三条规则。

    然而,第一条规则被证明更具实施性。所以我有三个问题:

    1. 是否可以使用具有前瞻和外观的简单扫描仪来实施第一条规则?
    2. 如果有可能那么有人已经完成了吗?
    3. 如果没有,那么我应该如何解决这个问题?
    4. 为了完整起见,这里有三条规则:

        
          
      • 当从左到右解析程序时,会遇到任何语法生成不允许的令牌(称为违规令牌),那么分号是如果满足以下一个或多个条件,则在违规令牌之前自动插入:

             
            
        1. 通过至少一个 LineTerminator 将违规令牌与上一个令牌分开。

        2.   
        3. 违规令牌为}

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

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

      •   
           

      但是,前面的规则还有一个额外的重要条件:如果分号将被解析为空语句,或者如果该分号将成为<的标题中的两个分号之一,则永远不会自动插入分号strong> for 语句(12.6.3部分)。

1 个答案:

答案 0 :(得分:4)

单独使用扫描仪(tokenizer)无法实现您想要的效果。这是因为要回答“我们这里需要分号吗?”你需要回答“下一个令牌是违规令牌吗?”要回答这个问题,你需要一个JavaScript语法,因为违规令牌被定义为语法在这个地方不允许的东西。

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

  • 向后迭代令牌(从最后一个开始,朝向文件的开头)
  • 如果当前令牌为IFFORWHILEVAR等:
    • 在令牌
    • 之前略过空白和评论
    • 如果当前令牌不是;,则插入一个

这种方法有效,因为错误不是随机的。人们总是犯同样的错误。大多数情况下,人们会在行结束后忘记;,并在关键字找到它们之前查找丢失的;

但这种方法只能让你到目前为止。如果必须可靠地找到所有缺失的分号,则必须编写JavaScript解析器(或重用现有的分号)。