同时分配和检查,并有一个很好的语法错误

我试图从第十一章的雄辩的Javascript书中重现一个语言分析器。

当我尝试这样做时:

function parseExpression(program) { program = skipSpace(program); var match, expr; if (match = /^"([^"]*)"/.exec(program)) expr = {type: "value", value: match[1]}; else if (match = /^\d+\b/.exec(program)) expr = {type: "value", value: Number(match[0])}; else if (match = /^[^\s(),"]+/.exec(program)) expr = {type: "word", name: match[0]}; else throw new SyntaxError("Unexpected syntax: " + program); return parseApply(expr, program.slice(match[0].length)); } 

我得到了一个非常奇怪的SyntaxError: Unexpected end of inputif

然而,像if (str = 'my string')这样的虚拟赋值完美地工作。 正则expression式是否与这种行为相混淆?

编辑:我试图debugging使用控制台。 这是我得到的:

 $ node > .load parser.js > function parseExpression(program) { ... program = skipSpace(program); ... var match, expr; ... if ((match = /^"([^"]*)"/.exec(program))) SyntaxError: Unexpected end of input at Object.exports.createScript (vm.js:24:10) at REPLServer.defaultEval (repl.js:225:25) at bound (domain.js:287:14) at REPLServer.runBound [as eval] (domain.js:300:12) at REPLServer.<anonymous> (repl.js:417:12) at emitOne (events.js:82:20) at REPLServer.emit (events.js:169:7) at REPLServer.Interface._onLine (readline.js:210:10) at REPLServer.Interface._line (readline.js:549:8) at REPLServer.Interface._ttyWrite (readline.js:884:20) > expr = {type: "value", value: match[1]}; ReferenceError: match is not defined at repl:1:31 at REPLServer.defaultEval (repl.js:252:27) at bound (domain.js:287:14) at REPLServer.runBound [as eval] (domain.js:300:12) at REPLServer.<anonymous> (repl.js:417:12) at emitOne (events.js:82:20) at REPLServer.emit (events.js:169:7) at REPLServer.Interface._onLine (readline.js:210:10) at REPLServer.Interface._line (readline.js:549:8) at REPLServer.Interface._ttyWrite (readline.js:884:20) > else if (match = /^\d+\b/.exec(program)) ... expr = {type: "value", value: Number(match[0])}; ... else if (match = /^[^\s(),"]+/.exec(program)) SyntaxError: Unexpected token else at Object.exports.createScript (vm.js:24:10) at REPLServer.defaultEval (repl.js:225:25) at bound (domain.js:287:14) at REPLServer.runBound [as eval] (domain.js:300:12) at REPLServer.<anonymous> (repl.js:417:12) at emitOne (events.js:82:20) at REPLServer.emit (events.js:169:7) at REPLServer.Interface._onLine (readline.js:210:10) at REPLServer.Interface._line (readline.js:549:8) at REPLServer.Interface._ttyWrite (readline.js:884:20) > expr = {type: "word", name: match[0]}; ReferenceError: match is not defined at repl:1:29 at REPLServer.defaultEval (repl.js:252:27) at bound (domain.js:287:14) at REPLServer.runBound [as eval] (domain.js:300:12) at REPLServer.<anonymous> (repl.js:417:12) at emitOne (events.js:82:20) at REPLServer.emit (events.js:169:7) at REPLServer.Interface._onLine (readline.js:210:10) at REPLServer.Interface._line (readline.js:549:8) at REPLServer.Interface._ttyWrite (readline.js:884:20) > else ... throw new SyntaxError("Unexpected syntax: " + program); ... return parseApply(expr, program.slice(match[0].length)); ... } 

节点似乎在正则expression式中存在一个问题,通过转义它们,函数parsing正确。

 function parseExpression(program) { program = skipSpace(program); var match, expr; if ((match = /^\"([^\"]*)\"/.exec(program))) expr = {type: "value", value: match[1]}; } 

你的代码没有错:

 C:\test>node -v v5.7.0 C:\test>node > .load parser.js > function parseExpression(program) { ... program = skipSpace(program); ... var match, expr; ... if (match = /^"([^"]*)"/.exec(program)) ... expr = {type: "value", value: match[1]}; ... else if (match = /^\d+\b/.exec(program)) ... expr = {type: "value", value: Number(match[0])}; ... else if (match = /^[^\s(),"]+/.exec(program)) ... expr = {type: "word", name: match[0]}; ... else ... throw new SyntaxError("Unexpected syntax: " + program); ... ... return parseApply(expr, program.slice(match[0].length)); ... } undefined > 

如果它不适合你,我会说这是一个Node的bug,会影响你的版本(你不会说哪一个),也许#5113 repl不能在正则expression式中处理单引号,当在一个函数内 ):

当我尝试在repl中input以下内容时,出现'SyntaxError:意外的input结束'

 var someFunction = function(s) { s = s.replace(/'/g, ''); } 

然而, s = s.replace(/'/g, '')本身在一个新行上是可以的。 难道我做错了什么?

该bug在Node / 5.7.0上得到了修复。

我有同样的问题试图在节点v6.10.3上运行此代码。 正如其他人所说的那样,我在正则expression式中脱离了引号,结束了工作。