1. ホーム
  2. c++

[解決済み] Antlrの利点(lex/yacc/bisonなどに対して) [終了しました]

2022-05-02 08:35:46

質問

私は過去に様々なプロジェクトでlexとyacc(通常はbison)を使用してきました。さらに、何十年も前のlex/yacc文法に基づいたコードをサポートしなければならなかったこともあります。ですから、専門家ではないものの、ツールを使いこなすことはできます。

過去に様々なフォーラムでAntlrについての肯定的なコメントを見ましたが、私が見逃していることがあるのではないかと思っています。そこで、もし両方を使ったことがあるのなら、Antlrのどこが優れているか、またはより高度か教えてください。私の現在の制約は、私はC++のショップで働いており、出荷する製品にはJavaが含まれないので、結果のパーサーはそのルールに従わなければならないことです。

どのように解決するのですか?

更新/警告 この回答は古くなっている可能性があります


大きな違いは、ANTLR は LL(*) パーサーを生成するのに対し、YACC と Bison はいずれも LALR のパーサーを生成することです。 これは多くのアプリケーションにとって重要な違いであり、最も明白なのは演算子です。

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLRはこの文法をそのまま扱うことは全くできない。 ANTLR(または他の LL パーサー生成器)を使用するには、この文法を左回帰式でないものに変換する必要がある。 しかし、Bisonはこの形式の文法に何の問題もない。 と'-'を左結合演算子として宣言する必要があるが、これは左再帰のために厳密には必要ない。 より良い例は、ディスパッチであろう。

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

の両方が expractuals のルールは左回帰式である。 これにより、複数のレジスタや不要な流出を避けることができるため、コード生成時にはるかに効率的なASTが生成されます(左向きの木は折りたたむことができますが、右向きの木は折りたたむことができません)。

個人的な好みで言えば、LALR文法は構築やデバッグが非常に楽だと思います。 欠点は、shift-reduce や (恐ろしい) reduce-reduce のような、やや不可解なエラーに対処しなければならないことです。 これらはパーサーを生成するときに Bison が検出するエラーなので、エンドユーザーの使用感には影響しませんが、開発プロセスを少し面白くすることができます。 ANTLR が YACC/Bison よりも使いやすいと一般に考えられているのは、まさにこのためです。