JavaScript语言分析:区分函数表达式和声明

时间:2014-11-30 20:25:57

标签: javascript parsing expression declaration abstract-syntax-tree

假设我正在创建一个仅与解析函数有关的简单JavaScript语言解析器。

我需要区分function "declarations"/"statements"function expressions。因为它们看起来几乎相同,我想我需要知道使用function的上下文。

我想我可以通过前面的标记来确定函数表达式。我认为以下算法可能有效:

  • 如果令牌是“功能”,那么
    • 如果以前的代币是operator,则 除了“关闭”运算符,如“]”,“}”或“)”,或者 如果前一个标记是“:”,那么
      • 功能是一种功能表达。
    • 否则
      • 功能是一种功能声明。

我能指望此算法正确判断function是声明还是表达式?如果它有缺陷,应该修复什么?或者,如果仅仅通过查看前一个标记就无法区分表单,那么我怎样才能以最少的努力来区分表单呢?

(我知道Esprima和co。存在。我想用不同的语言实现 native 解析器。)

1 个答案:

答案 0 :(得分:2)

我也在用JavaCC编写一个JavaScript parser - 用于Java。它是“时尚”吗? :)

我不是专家,所以我的术语可能有点家庭,请原谅。

如果我理解你的想法,似乎你想在词汇层面上区分函数声明和表达式。我认为这是一种错误的方式。 JavaScript有一个非常棘手的语法,这可能与函数声明一起使用,但是你将会遇到各种各样的问题。其中两个最复杂的是自动分号插入和正则表达式与分割。

现在回答你的问题。

语法:

FunctionDeclaration :
    function Identifier ( FormalParameterList_opt ) { FunctionBody }

FunctionExpression :
    function Identifier_opt ( FormalParameterList_opt ) { FunctionBody }

一个案例function (很容易。没有标识符 - 不能是FunctionDeclaration。但是,这并不能保证此 可以FunctionExpression:顶层的function () {}在语法上不正确。

FunctionExpression可能会出现在表达式可能显示的位置except for ExpressionStatement

所以问题是,你能否可靠地找出你是否可以在某个地方词汇表达一个表达式(即只看上一个令牌)。

我认为这可能相当困难。看一下my analysis的类似问题(从词汇上检测正则表达式)。

对于你的算法:

  • 如果令牌是“功能”,那么
    • 如果以前的令牌是运营商, 除了“关闭”运算符,如“]”,“}”或“)”,或者 如果前一个标记是“:”,那么
      • 功能是一种功能表达。
    • 否则
      • 功能是一种功能声明。

如果上一个令牌是/怎么办?接下来是function?你会认为这是一个函数表达式,但这可能是一个正则表达式文字。

同样:并不意味着这是一个函数表达式,这可能是无效

label: function() {}

我还认为ASI可能会出现进一步的并发症。考虑:

i++
function a() {}

++function之前的后缀运算符,但function a() {}是函数声明,在它之前会自动插入分号。

所以我认为你的算法不正确。而且我不确定你是否可以通过简单地查看几个以前的令牌来逃脱。