0

在 Ruby 中,redo可以使用关键字返回到循环的开头而不消耗输入。我想对for...ofJavaScript 中的循环做同样的事情。

const scan = lexer => function* (string) {
  let [token, table] = lexer;

  for (const character of string) {
    const next = table.get(character);

    if (next) {
      [token, table] = next.value;
    } else if (token) {
      yield token.value;
      [token, table] = lexer;
      // redo the current iteration without consuming input
    } else {
      throw new SyntaxError("Unexpected character", character);
    }
  }

  if (token) yield token.value;
  else throw new SyntaxError("Unexpected end of input");
}

通常,您只需不增加常规for循环的索引即可。但是,我必须使用for...of循环,因为它循环遍历字符串的 Unicode 代码点,而常规for循环将遍历字符串的 UTF-16 代码单元。

如何在不重复代码的情况下回到循环的开头?

4

1 回答 1

1

只需使用内部循环:

 for (const character of string) {
   while(true) {
     const next = table.get(character);       
     if (next) {
       [token, table] = next.value;
       break;
     } else if (token) {
       yield token.value;
       [token, table] = lexer;      
       // don't break, redo
     } else {
       throw new SyntaxError("Unexpected character", character);
       break;
    }
  }
}

重新启动整个循环

在您的情况下,它实际上非常简单:

 yield* scan(lexer)(string);
 return;

如果您不想重新启动整个功能,请添加 IIFE 并回忆一下:

 yield* (function redo*() {
   //...
  yield* redo();
  return;
})();

如果您真的需要跳跃,请使用标签(请不要):

 restart: while(true) {
  // do stuff
  continue restart;
  //...
  break;
}
于 2019-08-31T22:17:02.697 回答