简体   繁体   English

无法使用Esprima / Acorn解析函数:意外令牌'('

[英]Unable to parse function with Esprima/Acorn: unexpected token '('

I am able to parse arrow functions using Esprima and Acorn, but using normal functions gives an error: 我可以使用Esprima和Acorn解析箭头函数,但是使用普通函数会出现错误:

const esprima = require('esprima');
const acorn = require('acorn');

console.log(esprima.parseScript(` () => { console.log('Test')}`)); //works
console.log(acorn.parse(` () => { console.log('Test') }`); //works

console.log(esprima.parseScript(`function () { console.log('Test')}`)); // Unexpected token
console.log(acorn.parse(`function () { console.log('Test') }`); //Unexpected token

Any suggestions? 有什么建议么?

tl;dr tl; dr

If the line begins with the token function , it is a FunctionDeclaration , not a FunctionExpression . 如果该行以令牌function开头,则它是FunctionDeclaration ,而不是FunctionExpression And a function declaration requires an identifier (in a FunctionExpression it is optional ). 函数声明需要一个标识符 (在FunctionExpression中, 它是可选的 )。

-------- --------

The way that function () { console.log('Test') } code is written, makes it a function declaration ( FunctionDeclaration ) , not a function expression. 编写function () { console.log('Test') }代码的方式使它成为函数声明FunctionDeclaration ,而不是函数表达式。 And a function declaration expects an identifier (in a function expression it is optional ). 函数声明需要一个标识符(在函数表达式中, 它是可选的 )。

Try it in Chrome console, you'll get the same error. 在Chrome控制台中尝试该操作,您会收到相同的错误。

To understand, you'll have to look into the grammar os ES6 (more below). 要理解,您必须研究语法os ES6 (更多内容请参见下文)。

The () => {} ( ArrowFunction ) is always an expression (specifically, believe it or not, an AssignmentExpression ). () => {}ArrowFunction始终是一个表达式(具体地说,不管您信不信,都是一个AssignmentExpression )。


A JavaScript, in ES6, Script is roughly a sequence of statements ( StatementList , which is a sequence of StatementListItem s). 在ES6中,JavaScript 脚本大致是一个语句序列( StatementList ,它是StatementListItem的序列)。

A StatementListItem is a Statement or a Declaration . StatementListItem声明声明

Between Statement or a Declaration , the only possible expression is ExpressionStatement . StatementDeclaration之间 ,唯一可能的表达式是ExpressionStatement

ExpressionStatement is nothing more than an Expression . ExpressionStatement只是一个Expression

And in Expression you find the FunctionExpression . Expression中找到FunctionExpression

Because they start with the same token, I believe the FunctionDeclaration takes precedence over the FunctionExpression (the former is "less deep" down the grammar). 因为它们以相同的标记开头,所以我认为FunctionDeclaration优先于FunctionExpression (前者在语法上不那么“深入”)。 So the parser consumes the token function an expects the FunctionDeclaration to continue, throwing the error. 因此,解析器使用令牌function并期望FunctionDeclaration继续执行,并引发错误。


Getting rid of the error 摆脱错误

You can add an identifier, fulfilling the FunctionDeclaration 's requirements: 您可以添加满足FunctionDeclaration要求的标识符:

console.log(esprima.parseScript(`function test() { console.log('Test')}`));
console.log(acorn.parse(`function test() { console.log('Test') }`);

But, again, that makes it a FunctionDeclaration. 但是,这又使其成为FunctionDeclaration。 To make your code a function expression alone, as pointed by @JaredSmith in comments , wrap it into ( / ) s: 要使代码单独成为函数表达式(如@JaredSmith注释中所指出的那样 ),请将其包装到( / )

console.log(esprima.parseScript(`(function () { console.log('Test')} )`));
console.log(acorn.parse(`(function () { console.log('Test') } )`);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM