29

Vala のドキュメントによると、「0.3.1 より前の Vala のパーサーは、クラシックな flex スキャナーと Bison LALR パーサーの組み合わせでした。しかし、コミット eba85aの時点では、パーサーは手作りの再帰降下パーサーです。」私の質問は:なぜですか?

この質問は、パーサー ジェネレーターを使用していない任意のコンパイラーに向けられる可能性があります。パーサージェネレーターから手作りのパーサーへのこのような移行の長所と短所は何ですか? コンパイラにパーサー ジェネレーター (Bison、ANTLR) を使用することの欠点は何ですか?

補足的なコメントとして: 私が Vala に興味を持っているのは、特に、最新の機能とクリーンな構文を備えた言語でありながら、「ネイティブ」および「管理されていない」高水準言語 (Vala の場合は C) にコンパイルできるという考えが好きだからです。今のところヴァラしか見つかっていません。Vala (または同様の言語) を C++ にコンパイルできるようにして (Qt ライブラリに支えられて) 楽しんでみようと考えています。しかし、完全に新しい言語を発明したくないので、既存の文法を取り入れようと考えています。明らかに、手作りのパーサーには、私が再利用できる正式な文法が書かれていません。このアイデアに対するあなたのコメントは大歓迎です (全体のアイデアはばかげていますか?)。

4

5 に答える 5

16

LR(1) および LALR(1) パーサーは、次の 2 つの理由から非常に厄介です。

  1. パーサー ジェネレーターは、有用なエラー メッセージを生成するのが得意ではありません。
  2. C スタイルの if-else ブロックのような特定の種類のあいまいさは、文法を書くのを非常に苦痛にします。

一方、LL(1) 文法は、これらの両方ではるかに優れています。LL(1) 文法の構造により、再帰降下パーサーとしてエンコードするのが非常に簡単になります。

また、Vala の場合、パーサーとコンパイラ自体がライブラリとして提供されるため、Vala コンパイラ ライブラリを使用して Vala コンパイラ用のカスタム バックエンドを構築し、すべての解析と型チェックなどを無料で取得できます。

于 2013-03-28T03:38:21.117 に答える
2

これが決定的なものではないことはわかっています。あなたの質問が特にヴァラに関連していない場合、私は気にしませんが、それらは...

当時、私はプロジェクトにあまり深く関わっていなかったので、詳細の一部については明確ではありませんが、ヴァラが切り替えたときの大きな理由はドッグフーディングでした. それが主な動機だったかどうかは定かではありませんが、それが要因だったことは覚えています。

メンテナンス性も課題でした。そのパッチは、C/Bison/YACC で書かれたより大きなパーサー (後者の 2 つについて十分な経験を持っている人は比較的少ない) を、Vala のより小さなパーサー (valac の作業に関心のあるほとんどの人がおそらく知っていて、使い慣れている) に置き換えました。

より良いエラー報告も目標でした、IIRC.

それが要因だったのかどうかはまったくわかりませんが、手書きのパーサーは再帰降下パーサーです。私はANTLRがそれらを生成することを知っています.ANTLRはJavaで書かれており、かなり重い依存関係があります.

補足的なコメントとして: 私が Vala に興味を持っているのは、特に、最新の機能とクリーンな構文を備えた言語でありながら、「ネイティブ」および「管理されていない」高水準言語 (Vala の場合は C) にコンパイルできるという考えが好きだからです。今のところヴァラしか見つかっていません。Vala (または同様の言語) を C++ にコンパイルできるようにして (Qt ライブラリに支えられて) 楽しんでみようと考えています。しかし、完全に新しい言語を発明したくないので、既存の文法を取り入れようと考えています。明らかに、手作りのパーサーには、私が再利用できる正式な文法が書かれていません。このアイデアに対するあなたのコメントは大歓迎です (全体のアイデアはばかげていますか?)。

多くの Vala は実際には GObject によって下された決定を反映したものであり、C++/Qt では同じように機能する場合とそうでない場合があります。あなたの目標が valac の GObject/C を Qt/C++ に置き換えることである場合、おそらく予想以上の作業が必要になります。ただし、Vala から C++ および Qt ライブラリにアクセスできるようにしたいだけであれば、それは確かに可能です。実際、Luca Bruno は約 1 年前にこれに取り組み始めました ( wip/cppブランチを参照)。技術的な問題ではなく、時間がないため、しばらく活動が見られませんでした。

于 2013-03-29T01:27:28.747 に答える
0

Vala のドキュメントによると、「0.3.1 より前の Vala のパーサーは、従来のフレックス スキャナーと Bison LALR パーサーの組み合わせでした。しかし、コミット eba85a の時点では、パーサーは手作りの再帰降下パーサーです。」私の質問は:なぜですか?

ここでは特に Vala について質問していますが、この質問はパーサー ジェネレーターを使用していない任意のコンパイラーに向けられている可能性があります。パーサージェネレーターから手作りのパーサーへのこのような移行の長所と短所は何ですか? コンパイラにパーサー ジェネレーター (Bison、ANTLR) を使用することの欠点は何ですか?

おそらくプログラマーは、パーサー ジェネレーターが見つけられなかったいくつかの最適化手段を発見しました。これらの最適化手段には、まったく異なる解析アルゴリズムが必要でした。あるいは、おそらくパーサー ジェネレーターは C89 でコードを生成し、プログラマーは C99 または C11 のリファクタリングが読みやすさを向上させると判断しました。

補足的なコメントとして: 私が Vala に興味を持っているのは、特に、最新の機能とクリーンな構文を備えた言語でありながら、「ネイティブ」および「管理されていない」高水準言語 (Vala の場合は C) にコンパイルできるという考えが好きだからです。

簡単なメモ: C はネイティブではありません。ポータビリティに根ざしており、ポーティング時にプログラマーを悩ませていたハードウェア/OS 固有の詳細を抽象化するように設計されています。たとえば、OS やファイルシステムごとにまったく異なるfopenを使用することの苦痛を考えてみてください。単に機能が異なるだけでなく、入力と出力の期待も異なるという意味です。異なる引数、異なる戻り値。同様に、C11 では移植可能なスレッドが導入されています。スレッドを使用するコードは、同じ C11 準拠のコードを使用して、スレッドを実装するすべての OS をターゲットにすることができます。

私はこれまでにヴァラを見つけました。Vala (または同様の言語) を C++ にコンパイルできるようにして (Qt ライブラリに支えられて) 楽しんでみようと考えています。しかし、完全に新しい言語を発明したくないので、既存の文法を取り入れようと考えています。明らかに手作りのパーサーには、私が再利用できる正式な文法が書かれていません。このアイデアに対するあなたのコメントは大歓迎です (全体のアイデアはばかげていますか?)。

手作業で作成されたパーサーを使用して C++ コードを生成することは、ほとんど労力をかけずに実行できる可能性があるため、このオプションをすぐに放り出すつもりはありません。古い flex/bison パーサー ジェネレーターの方が便利かもしれませんし、そうでないかもしれません。ただし、これが唯一の選択肢ではありません。いずれにせよ、私は仕様を広範囲に研究したくなるでしょう。

于 2013-03-28T02:59:36.473 に答える
0

これらの著者がバイソンから RD に移行したのは興味深いことです。ほとんどの人は反対方向に行くでしょう。

Vala の作成者が行ったことを行う唯一の本当の理由は、より優れたエラー回復であるか、または文法があまりきれいではないことです。

ほとんどの新しい言語は、作成者が独自の新しい言語の感触をつかみ、自分が何をしたいのかを正確に理解するにつれて、手書きのパーサーから始まることがわかると思います。また、作成者がコンパイラの書き方を学ぶ場合もあります。C は、C++ と同様に典型的な例です。進化の後半では、生成されたパーサーが代用される場合があります。一方、既存の標準言語用のコンパイラは、パーサー ジェネレーターを介して、場合によっては既存の文法を介して、より迅速に開発できます。製品化までの時間は、これらのプロジェクトの重要なビジネス パラメータです。

于 2013-03-29T00:04:11.373 に答える