ですから、私はPythonパーサーであるLeplチュートリアルToken(Real())
を進めていますが、との違いが正確に何であるかを完全に理解することはできませんReal()
。関数に関するドキュメントを見つけましたが、かなり役に立ちません。
では、Token()クラスは正確に何をするのでしょうか?通常のLeplクラスと異なるのはなぜですか?
ですから、私はPythonパーサーであるLeplチュートリアルToken(Real())
を進めていますが、との違いが正確に何であるかを完全に理解することはできませんReal()
。関数に関するドキュメントを見つけましたが、かなり役に立ちません。
では、Token()クラスは正確に何をするのでしょうか?通常のLeplクラスと異なるのはなぜですか?
通常、LEPLは、入力にある文字のストリームを操作します。これは簡単ですが、これまで見てきたように、空白など、合法であるが無視される場合は、無視するために多くの冗長なルールが必要になります。
この問題には一般的な解決策があります。つまり、最初に入力文字列を実行して、この問題やその他の注意をそらす比較的単純なオートマトンを実行します。入力を細かく分割し(たとえば、数字、識別子、演算子など)、無視された部分(たとえば、コメントや空白)を取り除きます。これにより、パーサーの残りの部分が単純になりますが、LEPLのデフォルトモデルには、このオートマトンの場所がありません。これは、トークナイザーまたは字句解析プログラム(略して字句解析プログラム)と呼ばれます。
各種類のトークンは通常、[+-][0-9]+
整数など、各トークンに何が入るかを説明する正規表現として定義されます。でそれを行うことができます(場合によってはそうする必要があります)Token()
。たとえばToken('a+b+')
、正規表現が一致するのと同じ量の入力を消費するパーサーを提供し、それを単一の文字列として返します。ほとんどの場合、これらのパーサーは他のすべてのパーサーと同じように機能します。最も重要なことは、これらを同じ方法で組み合わせることができることです。たとえば、動作し、 2つの文字列を生成し、まったく同等でToken('a+') & Token('b+')
あることを除いて、前の機能と同等です。これまでのところ、これらはいくつかの文法のいくつかの基本的な構成要素の単なる短い表記法です。LEPLのクラスのいくつかをで使用することもできますToken('a+') + Token('b+')
Token()
それを同等の正規表現に変換し、それをトークンとして使用します-たとえばToken(Literal('ab+'))
、ですToken(r'ab\+')
。
重要な違いと大きな利点の1つは、トークンを使用して、一致するトークンが他にない場合にドロップインして入力を破棄するパターンを指定できることです。デフォルトでは空白が破棄されるため、空白を無視するのは非常に簡単です(一部の場所で空白を必要とするパーサー)。欠点は、トークン以外のすべてのマッチャーをトークンでラップするか、自動的に変換できない場合は同等のルールを手動で作成する必要があることです。