我正在编写一个 JavaScript 预处理器,它会在必要的地方自动插入分号。不要问为什么。
现在我知道解决这个问题的一般方法是编写一个 JavaScript 解析器,并根据规范中的规则在必要时添加分号。但是我不想这样做,原因如下:
- 我不想写一个成熟的解析器。
- 我想保留评论和空白。
我已经(正确地)使用简单的扫描仪实现了自动分号插入的第二条和第三条规则。
然而,第一条规则被证明是实施起来更具挑战性。所以我有三个问题:
- 是否可以使用带有前瞻和后视的简单扫描仪来实现第一条规则?
- 如果可能,那么有人已经做到了吗?
- 如果不是那么我应该如何解决这个问题?
为了完整起见,这里是三个规则:
当从左到右解析程序时,遇到任何语法生成都不允许的标记(称为违规标记)时,如果出现以下一项或多项,则在违规标记之前自动插入分号条件为真:
违规标记与前一个标记至少有一个LineTerminator分开。
有问题的令牌是}。
当程序从左到右解析时,遇到输入令牌流的结尾,并且解析器无法将输入令牌流解析为单个完整的 ECMAScript Program,则在末尾自动插入分号输入流。
当程序从左到右解析时,遇到某个语法产生式允许的记号,但产生式是受限制的产生式,并且该记号将是紧跟注释之后的终端或非终端的第一个记号"[no LineTerminator here]" 在受限产生式中(因此这样的记号被称为受限记号),并且受限记号与前一个记号至少有一个LineTerminator分隔,然后在受限记号前自动插入分号.
但是,前面的规则还有一个额外的覆盖条件:如果分号随后将被解析为空语句,或者如果该分号将成为for语句标题中的两个分号之一(部分12.6.3 )。