JavaScript 语言解析:区分函数表达式和声明
JavaScript Language Parsing: Distinguish function expressions and declarations
假设我正在创建一个简单的JavaScript语言解析器,它只涉及解析函数。
我需要区分函数"声明"/"语句"和函数表达式。因为它们看起来几乎相同,所以我想我需要知道使用function
的上下文。
我想我可以通过前面的标记确定函数表达式。我认为以下算法可能有效:
- 如果令牌是"函数",则
- 如果上一个令牌是运算符,
除了"关闭"运算符,如"]"、"}"或"(",或
如果上一个标记是 ":",则- 函数
- 是函数表达式。
- 还
- 函数
- 是一个函数声明。
- 如果上一个令牌是运算符,
我是否可以期望此算法正确确定function
是声明还是表达式?如果有缺陷,应该修复什么?或者,如果仅通过查看以前的令牌无法区分表单,那么我如何以最少的努力区分表单?
(我知道Esprima和co.存在。我想用不同的语言实现本机解析器。
我也在写一个JavaScript解析器 - 用于Java,使用JavaCC。是"流行"吗?:)
我不是专家,所以我的术语可能有点家庭水平,请原谅。
如果我理解正确了你的想法,似乎你想在词汇级别区分函数声明和表达式。我认为这是一种错误的方式。JavaScript 有一个非常棘手的语法,这可能适用于函数声明,但你会一路遇到极端情况。最复杂的两个是自动分号插入和正则表达式与除法。
现在回答你的问题。
语法:
FunctionDeclaration :
function Identifier ( FormalParameterList_opt ) { FunctionBody }
FunctionExpression :
function Identifier_opt ( FormalParameterList_opt ) { FunctionBody }
一个案例function (
很容易。无标识符 - 不能是FunctionDeclaration
。然而,这并不能保证这可以FunctionExpression
:顶层的function () {}
在语法上是不正确的。
除 ExpressionStatement
之外,表达式可能出现的位置可能会出现FunctionExpression
。
所以问题是,您能否可靠地找出是否可以在词法上的某个地方期待表达式(即只是查看以前的令牌(。
我认为这可能相当困难。看看我对类似问题的分析(以词法检测正则表达式(。
为您算法:
- 如果令牌是"函数",则
- 如果上一个令牌是运算符,除了"关闭"运算符,如"]"、"}"或"(",或
如果上一个标记是 ":",则- 函数
- 是函数表达式。
- 还
- 函数
- 是一个函数声明。
- 如果上一个令牌是运算符,除了"关闭"运算符,如"]"、"}"或"(",或
如果以前的令牌是/
的怎么办?接下来function
呢?你会认为这是一个函数表达式,但这可能是一个正则表达式文字。
另外:
这并不意味着这是一个函数表达式,这可能是无效的:
label: function() {}
我还认为ASI可能会带来进一步的并发症。考虑:
i++
function a() {}
++
是前面的后缀运算符function
,但function a() {}
是一个函数声明,则在它前面自动插入了一个分号。
所以我认为你的算法不正确。而且我不确定您能否简单地查看以前的几个令牌。
- 能够在定义函数表达式之前使用它
- 函数表达式,返回回调函数
- JavaScript中的立即调用函数表达式(IIFE)-传递jQuery
- 函数声明与函数表达式之间的性能差异
- 立即调用函数表达式(IIFE)相对于普通函数的优势
- 如何防止 JS 缩小删除命名函数表达式的名称
- Angularjs 与 coffeescript 函数表达式中断
- JavaScript 混乱中的函数表达式
- 从ES6中的函数表达式访问类作用域
- 提升作为数组项的匿名函数表达式
- Javascript Mocha测试-测试函数表达式中的函数表达式
- 函数中的JavaScript函数表达式
- Javascript闭包覆盖函数表达式
- 函数表达式的词法作用域
- 请解释一下“;立即调用函数表达式“;以及“;自调用匿名函数”;
- JavaScript 中的函数语句和函数表达式
- ng-class 的函数表达式在 ng-click 时被调用
- 如何创建名称和主体存储在不同变量中的 JavaScript 函数表达式
- Object.Prototype 方法和 IIFE(立即调用的函数表达式)中的“use strict”
- 全局范围内的函数表达式与函数声明的区别