プログラミング
Show HN: Yantra – C++向けLALR(1)パーサー生成ツール
Show HN: Yantra – an LALR(1) parser generator for C++ (github.com)
要約
Yantraは、C++で利用できるLALR(1)パーサー生成ツールです。従来のパーサー生成ツールとは異なり、構文解析中にセマンティックアクションを実行するのではなく、まず完全な抽象構文木(AST)を構築してから、それをトップダウンでウォークします。これにより、親ルールのアクションが子ノードの処理前に実行されるなど、より柔軟な構文解析が可能になります。
全文翻訳
YantraはC++のパーサー生成ツールです。レキサー、パーサー、ASTウォーカーがすべて1つのツールから生成されます。
全体でASTを構築してから、それをウォークします。
ほとんどのLALRパーサー生成ツール(Yacc、Bison、Lemon)は、ボトムアップで各ルールがリデュースされる際にセマンティックアクションを実行します。
これは、ルールのアクションが実行される時点で、その親がどのようなものかまだ分からないことを意味します。これにより、多くの文法で手作りのASTクラスと、兄弟ノードを先読みしたり、より多くのコンテキストが利用可能になるまで決定を延期したりする必要がある場合に別のウォークパスが必要になります。
一方、Yantraは常にまずAST全体を構築し、その後別のパスでトップダウンでウォークし、処理を進めながらセマンティックアクションを呼び出します。親ルールの親ルールのアクションは、子ノードが訪問される前に実行される可能性があります。
1つの文法で複数のウォーカーを定義できます。例えば、同じパースからC++をエミットするものとJavaをエミットするものの両方です。ASTとウォーカークラスは両方とも生成されます。
小さな例(完全版、コンパイルコマンド付きはREADMEにあります):
```cpp
start := expr;
expr := expr(a) PLUS expr(b)
{
std::cout << "Adding" << std::endl;
}
expr := NUMBER(N)
{
std::cout << "Number: " << N.text << std::endl;
}
NUMBER := "\d+";
PLUS := "\+";
WS := "\s+"!;
```
これを "1 + 2 + 3" で実行すると、以下のように出力されます:
```cpp
Adding
Number: 1
Adding
Number: 2
Number: 3
```
外側の "Adding"、つまりツリーのルートが、子ノードのいずれよりも先に表示されます。これは、すべてのアクションが実行される前にツリー全体が存在しているからこそ可能です。
その他の機能:モードサポート付きの統合レキサー(ネストされたコメントなどのため)、生成されたmain()を含むオプションの統合単一ファイル出力モード、C++23、MITライセンス。
まだ新しく(0.5.1、1.0未満)、単一メンテナーであるため、初期段階と見なしてください。
完成度が高く見えるよりも、何が壊れるかを知りたいです。
既知の制限事項は以下にリストされています。
https://github.com/TantrixAuto/yantra/blob/main/docs/known_limitations.md
リポジトリ: https://github.com/TantrixAuto/yantra
フィードバックや質問は歓迎します。いつでも対応します。