パーサジェネレータはスキャナーを必要としません。しかし、使用しないとかなり頭がおかしくなります。
パーサージェネレーターによって構築されたパーサーは、トークンと呼ばれる限り、何をフィードしてもかまいません。
スキャナーなしでパーサージェネレーターを使用してビルドするには、文法を文字レベルまで定義し、個々の文字をトークンとしてパーサーにフィードします。
これがおかしい理由は、構文解析が字句解析よりも複雑なアクティビティであるためです。レクサーを有限状態マシンとして構築できます。これは、「比較して次の状態にジャンプする」のとほぼ同じようにマシンコードに変換されます。スピードに関しては、それを打ち負かすのは本当に難しいです。パーサージェネレーターは、再帰下降予測解析(ANTLRなどのほとんどのLLジェネレーターの場合)を実行するパーサーを構築するか、ハッシュ、バイナリまたは線形検索などによってテーブルルックアップを実行します。したがって、パーサーは、レクサーがトークンに費やすよりもはるかに多くのエネルギーをトークンに費やします。キャラクター。
文字をトークンとしてパーサーにフィードすると、それに応じて、同等のレクサーよりも多くのエネルギーが文字に費やされます。大量の入力テキストを処理する場合、何百万もの小さな入力ストリームに対して処理するか、いくつかの非常に大きな入力ストリームに対して処理するかにかかわらず、これは最終的に重要になります。
いわゆるスキャナーレスGLRパーサーは、トークンを使用するように設計されたGLRパーサーと比較して、このパフォーマンスの問題に悩まされています。
私の会社はツール、 DMS SoftwareReengineeringToolkitを構築しています これはGLRパーサーを使用します(そして、GLRパーサーを備えているため、知っているすべての一般的な言語と、知らない多くの奇妙な言語を正常に解析します)。私たちはスキャナーレスパーサーについて知っていて、速度差のためにそれらを実装しないことを選択しました。字句トークンを定義するための、古典的なスタイルの(ただし非常に強力な)LEXのようなサブシステムがあります。DMSが同じ入力を処理するXT(スキャナーレスGLRパーサーを備えたツール)ベースのツールに対してノーズツーノーズで行った1つのケースでは、DMSはXTパッケージの10倍の速度であるように見えました。公平を期すために、行われた実験はその場限りのものであり、繰り返されませんでしたが、それが私の疑いと一致したので、私はそれを繰り返す理由がわかりませんでした。YMMV。そしてもちろん、スキャナーレスにしたい場合は、すでに指摘したように、文字端末を使用して文法を書くのは非常に簡単です。
GLRスキャナーレスパーサーには、ほとんどの人にとって重要ではないもう1つの非常に優れたプロパティがあります。スキャナーレスパーサー用に2つの別々の文法を取り、それらを文字通り連結しても、パーサーを取得できます(多くの場合、あいまいさが多くなります)。これは、ある言語を別の言語に埋め込んで構築する場合に非常に重要です。それがあなたがしていることではない場合、これは単なる学術的な好奇心です。
そして、AFAIK、エルクハウンドはスキャナーレスではありません。(私はこれについて間違っている可能性があります)。(編集:2/10:私が間違っていたようです。私の人生で初めてではありません:)