2009-04-29 8 views
6

私は様々なライブラリのregexpsのように振る舞うパーサーがないと思われました。たとえば、BNFというパーサーがないようです。なぜオンラインパーサーは正規表現で停止しているようですか?

確かに、は順番に、CFGを解析することができますが、中間のステップなしにそれを行うことができ、ライブラリがあるようには思えない、コードを生成することANTLRYaccおよび他の多くのようなものがあります。

私はPackrat parserを書くことに興味があり、regexpsに関連付けられたネストされた括弧のついたクォークをすべてブートすることに興味がありますが(それはおそらくもっとスポーツのために)、どういうわけか、別の休止問題のような沼地に入っていくだけです。

これらのパーサーの技術的/理論的な制限はありますか、何か不足していますか?

答えて

4

私はもっと文化的なものだと思います。文脈自由文法の使用は、主にコンパイラに限定されています。コンパイラは通常、それぞれの生成規則に関連付けられたコードを持っています。いくつかの言語では、コールバックをシミュレートするよりもコードを出力する方が簡単です。他の例では、パーサーライブラリが表示されます:例えば、Haskellのパーサーコンビネータ。一方、正規表現はgrepのようなツールで広く使われています。ユーザーが新しい正規表現を与えるたびにCコンパイラを実行するのは不便です。

0

本格的な文脈自由文法は、それほど混乱しないので、文法的に密で理解できない文法を使わなければ、それらをさらに混乱させることはありませんか?

あなたが何を求めているのか分かりません。正規表現のようなものを作成しようとしていますが、文脈自由文法のために作成しようとしていますか?同様に$var =~ /expr = expr + expr/(Perlで)を使用し、一致するのは"1 + 1"または"1 + 1 + 1"または"1 + 1 + 1 + 1 + 1 + ..."ですか?私はこれの限界の1つが構文になると思います:約3つ以上の規則を持つことは、あなたの "文法表現"を現代の正規表現よりもさらに読むことができなくなります。

+0

CFGを解析する機能よりも(まだ未定の)実装を主張しているようですね。確かに、正規表現は訓練されていない目には隠されています。たぶん、文脈自由な言語は、もっと謎かもしれません。しかし、それはポイントではなかった。要点は、なぜコードジェネレータだけが存在し、今日の正規表現と同じように、関数/オブジェクトに入れて、それらの中からテキストの一致ブロックを得ることができないということです。 –

+0

通常、パーサーを使用する人は、テキストを見て文法に合っているかどうかを確認するだけではなく、多くのことを行うことを目指しています。それには何か問題はありませんが、ほとんどのパーサーはかなり多くを行います。 –

+0

さらに、実装はある時点で対処しなければならない技術的な制限であり、技術的/理論的な制限について尋ねました。 –

0

私はあなたに遭遇するものを見る唯一のものです。ほとんどのパーサジェネレータには処理のための埋め込みコードが含まれており、その作業を行うには評価が必要です。

アクションの名前を付けることと、アクションの名前とそれを行うargsを取る「アクション」関数を作成することです。

0

C++で理論的にはBoost Spiritとすることができますが、主に静的文法のために作られています。私はこれが一般的ではない理由は、CFGは正規表現ほど一般的ではないということです。私はコンパイラの構築を除いて文法を使用する必要はありませんでしたが、私は正規表現を何度も使ってきました。 CFGは一般に正規表現よりもはるかに複雑なので、YACCやANTLRのようなツールを使って静的にコードを生成するのは理にかなっています。

+0

私は、正規表現の使用が今日のCFGの要求であると思われるよりも一般的であることに同意します。しかし、Stack Overflowだけで正確に入れ子にされたset pf括弧を得ることに関して、私は数多くの質問に遭遇したので、CFGの使用があると確信しています。人々は正規表現だけを知っているので、おそらく彼らは求められていないでしょうか? –

+0

IIRC Boost :: Spiritは純粋なコンパイル時の実装です。文法の実行時の定義を許可する理由は何もわかりません。 – BCS

+0

ブーストスピリットは、実行時に使用できます。トークンを文法の最後に移動するだけです。 grammar = grammar >> ch_p( 'a'); – Zifre

2

Boost.Spiritはあなたの後ろのもののように見えます。

自分で作ってみたいと思っているのなら、私は最新のコンパイラプロジェクトにBNFCを使っていて、the grammar used in its own implementationを提供しています。これは良い出発点かもしれません...

+0

私は私の答えで言ったように、Boost.Spiritは動作しますが、静的文法を主な目的としています。 BNFCに言及してくれてありがとう、私は今私のコンパイラのために使用するかもしれません。それは本当に素晴らしいです! – Zifre

2

影には技術的/理論的制限がありません。私はなぜそれらがより一般的ではないのか言うことはできませんが、私はあなたが求めるこのような "オンライン"解析を提供する少なくとも1つのライブラリを知っています。

SimpleParseは、あなたのプログラムにあなたの毛むくじゃらのEBNF文法を単純に貼り付けることができ、すぐに物事を解析するためにそれを使用することができます。私はカスタム入力言語が必要だったいくつかのプロジェクトでそれを使用しましたが、実際には正式なビルドプロセスにコミットしたくありませんでした。ここで

は、私の頭の上から小さな例です:

decl = r""" 
    root := expr 
    expr := term, ("|", term)* 
    term := factor+ 
    factor := ("(" expr ")")/[a-z] 
""" 
parser = Parser(decl) 
success, trees, next = parser.parse("(a(b|def)|c)def") 

ハスケルとScalaのためのパーサコンビネータライブラリはまた、あなたのそれを使用するコードの同じチャンクであなたのパーサーのあなたの文法を表現してみましょう。ただし、実行時にユーザーが文法を入力できるようにすることはできません(これは、人々が文法を理解するのを助けるソフトウェアを作っている人にとっては興味深い)。

+0

あなたの有益な答えをありがとう! –

1

Pyparsing(http://pyparsing.wikispaces.com)にはpackrat解析の組み込みサポートがあり、純粋なPythonであるため、実際の実装を見ることができます。

関連する問題