私はコンビナトリアルGLRパーサーを実装しました。それらの中には、指定された文字または文字の範囲を消費するパーサがあります:"*?"の実装(怠惰な "*")コンビナトリアルGLRパーサーの正規表現パターン
char(·)
many(·)
0から無限回まで指定されたパーサを繰り返すコンビネータ。
例:"char('a').many()"
は、任意の数の文字列("a"
-s)と一致します。
しかしmany(·)
コンビネータは、たとえば、char('{') >> char('{') >> char('a'..'z').many() >> char('}') >> char('}')
は(">>"
はパーサのシーケンシャルチェーンである場合)に成功し、全体"{{foo}}some{{bar}}"
文字列を消費します、貪欲で、そう。
many(·)
の遅延バージョンを実装したいと思います。前の例で使用していたのは"{{foo}}"
だけです。どうやってやるの?
編集:
屋すべてのIを混同されることがあります。私のプログラムでは、パーサは「ステップ」を受け取り、「ステップ」のフォレストを返す関数(またはC++の点では「ファンクタ」)です。 「ステップ」は、OK型(パーサが入力の一部を正常に消費したことを意味します)とFAIL型(パーサがエラーに遭遇したことを意味します)の可能性があります。より多くの種類のステップがありますが、それらは補助的です。
Parser = f(Step) -> Collection of TreeNodes of Steps.
は、だから私は、解析する際に、入力、I:
必要な文法を表す複雑な構文解析機能を取得するために、単純な定義済みのパーサ機能を作曲します。
フォームからの最初のステップ。
複雑なパーサー関数に最初のステップを与えます。
フィルタツリーノードはOKのものだけを残します(入力にエラーがあった場合は最小限のFAIL-sを指定します)。
残ったステップの情報を収集します。
GLRの実装方法はまだわかりません。従来のGLRパーサは、文法全体からの情報を組み込んだモノリシックなパーサーテーブルを持っています。あなたはそれをやっていますか? –