4

必要な場所にセミコロンを自動的に挿入する JavaScript プリプロセッサを作成しています。理由を聞かないでください。

この問題に取り組む一般的な方法は、JavaScript パーサーを作成し、仕様の規則に従って必要に応じてセミコロンを追加することであることがわかりました。ただし、次の理由により、そうしたくありません。

  1. 私は本格的なパーサーを書きたくありません。
  2. コメントと空白を保持したい。

簡単なスキャナーを使用して、自動セミコロン挿入の 2 番目と 3 番目のルールを既に (正しく) 実装しています。

ただし、最初のルールは、実装がより困難であることがわかります。だから私は3つの質問があります:

  1. 先読みと後読みを備えた単純なスキャナーを使用して最初のルールを実装することは可能ですか?
  2. それが可能なら、誰かがすでにそれを行っていますか?
  3. そうでない場合、どうすればこの問題に取り組むことができますか?

完全を期すために、ここに 3 つのルールを示します。

  • プログラムが左から右に解析されるときに、文法のどの生成でも許可されていないトークン (問題のあるトークンと呼ばれる) が検出された場合、次の 1 つ以上の場合、問題のあるトークンの前にセミコロンが自動的に挿入されます。条件は真です:

    1. 問題のあるトークンは、少なくとも 1 つのLineTerminatorによって前のトークンから分離されています。

    2. 問題のあるトークンは}です。

  • プログラムが左から右に解析されるときに、トークンの入力ストリームの終わりが検出され、パーサーが入力トークン ストリームを単一の完全な ECMAScript Programとして解析できない場合、セミコロンが末尾に自動的に挿入されます。入力ストリーム。

  • プログラムが左から右に解析されるときに、文法の一部の生成によって許可されているトークンが検出されたが、生成が制限された生成であり、トークンが注釈の直後の終端または非終端の最初のトークンになる場合"[no LineTerminator here]" 制限されたプロダクション内 (したがって、そのようなトークンは制限されたトークンと呼ばれます) であり、制限されたトークンは少なくとも 1 つのLineTerminatorによって前のトークンから分離され、制限されたトークンの前にセミコロンが自動的に挿入されます。 .

ただし、前述のルールには追加のオーバーライド条件があります。セミコロンが空のステートメントとして解析される場合、またはそのセミコロンがforステートメントのヘッダーにある 2 つのセミコロンの 1 つになる場合、セミコロンは自動的に挿入されません(セクション12.6.3 )。

4

1 に答える 1

4

スキャナー (トークナイザー) だけで目的を達成する方法はありません。これは、「ここにセミコロンが必要ですか?」と答えるためです。「次のトークンは問題のあるトークンですか?」に答える必要があります。これに答えるには、JavaScript 文法が必要です。問題のあるトークンは、この場所では文法で許可されていないものとして定義されているからです。

すべてのトークンのリストを作成し、そのリストを 2 番目のステップで処理することにある程度成功しました (したがって、コンテキストが得られます)。このアプローチを使用すると、次のようなコードを記述していくつかの場所を修正できます。

  • トークンを逆方向に繰り返します (最後のトークンから始めて、ファイルの先頭に向かって)
  • 現在のトークンがIFFOR、などのWHILE場合VAR:
    • トークンの前の空白とコメントをスキップする
    • 現在のトークンが でない場合は、トークン;を挿入します

間違いはランダムではないため、このアプローチは機能します。人はいつも同じ過ちを犯します。ほとんどの場合、人々;は行末の後を忘れてしまい;、キーワードの前に抜けているものを探すことは、それらを見つける良い方法です。

しかし、このアプローチでは、これまでのところしか得られません。欠落しているすべてのセミコロンを確実に見つける必要がある場合は、JavaScript パーサーを作成する (または既存のパーサーを再利用する) 必要があります。

于 2013-02-25T14:22:16.340 に答える