J'essaie de reproduire un analyseur de langue du livre Javascript Eloquent au chapitre 11. Voir ici.

Quand j'essaye de faire ça:

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));
}

Je reçois un SyntaxError: Unexpected end of input très étrange du if.

Cependant, une affectation factice comme if (str = 'my string') fonctionne parfaitement. Le Regex joue-t-il avec ce comportement?

Edit: j'ai essayé de déboguer en utilisant la console. Voici ce que j'obtiens:

$ 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));
... }
1
sotaan 7 mars 2016 à 13:59

3 réponses

Meilleure réponse

Le nœud semble avoir un problème avec les caractères " dans l'expression régulière. En leur échappant, la fonction analyse correctement.

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

J'ai eu le même problème en essayant d'exécuter ce code sur Node v6.10.3. J'ai fini par travailler quand j'ai échappé aux guillemets à l'intérieur des expressions régulières comme d'autres l'ont dit.

0
Jdras 30 mai 2017 à 04:50

Il n'y a rien de mal dans votre code:

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
>

Si cela ne fonctionne pas pour vous, je dirais que c'est un bug Node qui affecte votre version (vous ne dites pas lequel exactement), peut-être # 5113 repl ne peut pas gérer les guillemets simples dans l'expression régulière, lorsqu'ils sont dans une fonction):

J'obtiens une «SyntaxError: Fin inattendue de l'entrée» lorsque j'essaie d'entrer ce qui suit dans la repl

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

Cependant, s = s.replace(/'/g, '') en soi sur une nouvelle ligne est OK. Suis-je faire quelque chose de mal?

Ce bogue a été corrigé sur Node / 5.7.0.

1
Álvaro González 11 mars 2016 à 09:49