6

これらのユーティリティに関して私が読んだほとんどの投稿は、通常、同じ効果を得るために他の方法を使用することを提案しています。たとえば、通常これらのツールに言及している質問には、次のいくつかを含む少なくとも1つの回答があります。

  • ブーストライブラリを使用します(ここに適切なブーストライブラリを挿入します)
  • DSLの使用を作成しないでください(ここにお気に入りのスクリプト言語を挿入してください)
  • Antlrの方が優れています

開発者を想定して...

  • ...C言語に慣れている
  • ...少なくとも1つのスクリプト言語(Python、Perlなど)を知っています
  • ...作業中のほぼすべてのプロジェクトで解析コードを作成する必要があります

だから私の質問は:

  • これらのユーティリティに適した適切な状況は何ですか?
  • yaccとlex(または派生物)よりも問題のより良い代替手段がない(合理的な)状況はありますか?
  • 実際の構文解析の問題で、yaccとlexの欠点に遭遇することがどれくらいの頻度で予想できますか?これらは、より最近の解決策によってより適切に対処されますか?
  • これらのツールにまだ精通していない開発者にとって、構文/イディオムの学習に時間を費やす価値はありますか?これらは他のソリューションとどのように比較されますか?
4

5 に答える 5

5

lex/yacc とその派生物が今日どこにでもあるように見える理由は、それらが他のツールよりもはるかに長く存在していること、文献ではるかに多く取り上げられていること、そして伝統的に Unix オペレーティング システムに付属していたことです。他のレクサーおよびパーサー生成ツールと比較する方法とはほとんど関係ありません。

どのツールを選択しても、学習曲線は常に重要です。したがって、特定のツールを数回使用し、比較的快適に使用できるようになると、別のツールを習得するために余分な労力を必要とすることはほとんどありません。それは当然のことです。

また、1960 年代後半から 1970 年代前半にかけて lex/yacc が作成されたとき、ハードウェアの制限が解析に深刻な問題をもたらしました。Yacc が使用するテーブル駆動型の LR 解析方法は、比較的小さな汎用プログラム ロジックを使用し、テープまたはディスク上のファイルに状態を保持することにより、小さなメモリ フットプリントで実装できるため、当時最も適していました。LL などのコード駆動型解析メソッドは、パーサー プログラムのコード自体が文法を表し、実行するには完全に RAM に収まる必要があり、RAM のスタックに状態を保持するため、最小メモリ フットプリントが大きくなりました。

メモリがより豊富になると、LL や PEG などのさまざまな解析方法と、それらの方法を使用してツールを構築する方法について、さらに多くの研究が行われました。これは、lex/yacc ファミリーの後に作成された代替ツールの多くが異なるタイプの文法を使用していることを意味します。ただし、文法タイプを切り替えると、かなりの学習曲線が発生します。LR 文法や LALR 文法などの 1 つのタイプの文法に慣れると、LL 文法などの別のタイプの文法を使用するツールに切り替えたくなる可能性は低くなります。

全体として、lex/yacc ファミリーのツールは一般に、文法や文法の競合をグラフィカルに視覚化したり、自動リファクタリングによって競合を解決したりするための洗練されたユーザー インターフェイスを備えていることが多い最近のツールよりも初歩的です。

したがって、パーサー ツールの使用経験がなく、いずれにせよ新しいツールを習得する必要がある場合は、文法と競合のグラフィカルな視覚化、自動リファクタリング、適切なドキュメントの入手可能性、言語など、他の要因を検討する必要があります。生成されたレクサー/パーサーを出力できるなど。「これは他の人が使用しているように見える」という理由だけでツールを選択しないでください。

lex/yacc または flex/bison を使用する理由として考えられるのは次のとおりです。

  • 開発者はすでに lex/yacc または flex/bison に精通しています
  • 開発者は LR/LALR 文法に最も精通しており、快適に使用できます。
  • 開発者は lex/yacc を扱った本をたくさん持っていますが、それ以外を扱った本はありません。
  • 開発者は将来の仕事のオファーが来ており、lex/yacc のスキルがあれば採用される可能性が高まると言われています。
  • 開発者は、他のツールの使用についてプロジェクト メンバー/利害関係者から同意を得ることができませんでした
  • 環境に lex/yacc がインストールされており、何らかの理由で他のツールをインストールできない
于 2010-03-10T05:54:08.047 に答える
1

これらのツールを学習する価値があるかどうかは、大きく依存します (ほぼ完全に、記述する解析コードの量、またはその一般的な順序でより多くのコードを記述することにどれだけ興味があるかによって異なります。私はそれらをかなり使用しており、非常に便利だと思います。 .

使用するツールは、多くの人が信じているほど大きな違いはありません。私が対処しなければならなかった入力の約 95% については、1 つの入力と別の入力との間に十分な違いがないため、単に私が最も慣れていて快適な入力を選択するのが最善です。

もちろん、lex と yacc は C (または C++) でアクションを作成します (そして、アクションを作成する必要があります)。それらに慣れていない場合は、お好みの言語 (Python や Java など) を使用および生成するツールを選択する方が間違いなく優れています。私としては、このようなツールを使い慣れていない、または使い慣れていない言語で使用することはお勧めしません。特に、コンパイラ エラーを生成するアクションでコードを記述した場合、問題を追跡する際に通常よりもコンパイラから得られるヘルプが大幅に少なくなる可能性があるため、問題を認識するために言語に十分精通している必要があります。コンパイラがどこで何かがおかしいことに気づいた場所についての最小限のヒントだけで。

于 2010-03-10T05:00:41.333 に答える
0

以前のプロジェクトでは、比較的技術者でない人でも簡単に使用できる方法で、任意のデータに対してクエリを生成できる方法が必要でした。データはCRMタイプのもの(つまり、名、姓、電子メールアドレスなど)でしたが、すべて異なるスキーマを持つ多くの異なるデータベースに対して機能することを目的としていました。

そこで、クエリを指定するための小さなDSLを開発しました(たとえば、[FirstName] ='Joe' AND [LastName]='Bloggs'は"JoeBloggs"と呼ばれるすべての人を選択します)。それにはいくつかのより複雑なオプションがありました。たとえば、特定のメディア(電子メール、SMSなど)でメッセージの受信をオプトアウトしたすべての人を選択する「optedout(medium)」構文がありました。特定のグループの全員を選択する「ingroup(xyz)」などがありました。

基本的に、「ingroup('GroupA')ではなくingroup('GroupA')」のようなクエリを指定できます。これは、次のようなSQLクエリに変換されます。

SELECT
    *
FROM
    Users
WHERE
    Users.UserID IN (SELECT UserID FROM GroupMemberships WHERE GroupID=2) AND
    Users.UserID NOT IN (SELECT UserID GroupMemberships WHERE GroupID=3)

(ご覧のとおり、クエリは可能な限り効率的ではありませんが、それがマシン生成で得られるものだと思います)。

私はそれのためにフレックス/バイソンを使用しませんでした、しかし私はパーサージェネレーターを使用しました(その名前は今のところ私から逃れています...)

于 2010-03-10T03:37:24.543 に答える
0

ドメイン固有言語をサポートするためだけに、新しい言語の作成を避けることはかなり良いアドバイスだと思います。既存の言語を使用して、ドメイン機能で拡張することは、時間を有効に活用できるようになります。

おそらく言語設計の研究のために、他の理由で新しい言語を作成しようとしている場合、これらのツールは少し時代遅れです。antlrなどの新しいジェネレーター、またはMLなどの新しい実装言語を使用すると、言語設計がはるかに簡単になります。

これらのツールを使用する正当な理由がある場合、それはおそらくそれらのレガシーのためです。強化する必要のある言語のスケルトンがすでにある場合があります。これは、これらのツールの1つにすでに実装されています。また、これらの古いツールについて書かれた膨大な量のチュートリアル情報の恩恵を受けるかもしれません。これらのツールについては、言語を実装するための新しくて洗練された方法のために書かれたコーパスはそれほど多くありません。

于 2010-03-10T03:38:53.257 に答える
0

私のオフィスにはプログラミング言語全体が実装されています。そのために使用します。これは、インタプリタをすばやく簡単に作成できるようにするためのものだと思います。おそらく、それらを使用してほとんどすべての種類のテキスト パーサーを作成できますが、多くの場合、A) 自分ですばやく作成する方が簡単であるか、B) それらが提供するよりも柔軟性が必要です。

于 2010-03-10T03:40:32.843 に答える