我正在编写一个JavaScript预处理器,它会在必要的地方自动插入分号。不要问为什么。
现在我知道解决这个问题的一般方法是编写一个JavaScript解析器,并根据规范中的rules在必要时添加分号。但是出于以下原因我不想这样做:
我已经(正确地)使用简单的扫描仪实现了自动分号插入的第二和第三条规则。
然而,第一条规则被证明更具实施性。所以我有三个问题:
为了完整起见,这里有三条规则:
当从左到右解析程序时,会遇到任何语法生成不允许的令牌(称为违规令牌),那么分号是如果满足以下一个或多个条件,则在违规令牌之前自动插入:
通过至少一个 LineTerminator 将违规令牌与上一个令牌分开。
违规令牌为} 。
当从左到右解析程序时,会遇到令牌输入流的末尾,并且解析器无法将输入令牌流解析为单个完整的ECMAScript 程序,然后在输入流的末尾自动插入分号。
当从左到右解析程序时,会遇到某些语法生成所允许的令牌,但是生产是限制生产并且令牌会紧跟在限制生产中注释“[no LineTerminator here]”之后的终端或非终端的第一个令牌(因此这样的令牌被称为受限令牌),并且受限制的令牌被分开在前一个令牌中至少有一个 LineTerminator ,然后在限制令牌之前自动插入分号。
但是,前面的规则还有一个额外的重要条件:如果分号将被解析为空语句,或者如果该分号将成为<的标题中的两个分号之一,则永远不会自动插入分号strong> for 语句(12.6.3部分)。
答案 0 :(得分:4)
单独使用扫描仪(tokenizer)无法实现您想要的效果。这是因为要回答“我们这里需要分号吗?”你需要回答“下一个令牌是违规令牌吗?”要回答这个问题,你需要一个JavaScript语法,因为违规令牌被定义为语法在这个地方不允许的东西。
我在创建所有令牌列表方面取得了一些成功,然后在第二步中处理该列表(所以我会有一些上下文)。使用这种方法,您可以通过编写如下代码来修复某些地方:
IF
,FOR
,WHILE
,VAR
等:
;
,则插入一个这种方法有效,因为错误不是随机的。人们总是犯同样的错误。大多数情况下,人们会在行结束后忘记;
,并在关键字找到它们之前查找丢失的;
。
但这种方法只能让你到目前为止。如果必须可靠地找到所有缺失的分号,则必须编写JavaScript解析器(或重用现有的分号)。