1

一連のステートメントを持つ C ライクな言語の文法を作成する場合、文法を定義する最も標準的な方法は何ですか?

私の考えは、次のようなことをすることです:

<program> ::= <statement>
<statement> ::= <statement-head><statement-tail>
<statement-head> ::= <if-statement> | <var-declaration> | <assignment> | <whatever>
<statement-tail> ::= ; | ;<statement>

しかし、それは私には少し不格好に感じます。作ることも考えました

<program> ::= <statement>*

また

<statement> ::= <statement-head> ; | <sequence>
<sequence>  ::= <statement> <statement>

タイププロダクション。

これを行うための標準的な方法または受け入れられている方法はありますか。ASTをできるだけきれいにしたい。

4

2 に答える 2

7

非常に一般的な方法は次のとおりです。

<block-statement> ::= '{' <statement-list> '}' ;
<statement-list> ::= /* empty */ | <statement-list> <statement> ;
<statement> ::= <whatever> ';' ;

そして、入力する代わりに実際のステートメントを定義します<whatever>。リストの非終端記号の定義にセミコロンを入れるよりも、個々のステートメントの一部として末尾のセミコロンを含める方がはるかにきれいに見えます。

于 2009-11-04T17:50:03.383 に答える
2

ここで C の BNF を見つけることができます。これは K&R から取られたものだと思います。また、適切なシーケンスの作成に関する詳細情報を提供するSQL BNF hereを確認することもできます。

これにより、いくつかの規則情報が提供されます。

AST 生成に関しては、定義がどのように「ぎこちない」ものであっても、すべての順列に対してソースを正しく解析することは問題ではありません。次に、アクションを追加して AST を構築します。

リダクションで問題が発生する可能性があるため、LL パーサーや LR パーサーなどの適切なパーサー ジェネレーター用にグラマーを構築していることを確認してください。これは、一部のルールを新しい方法で書き直す必要があることを意味します。左再帰の削除については、こちらを参照してください。

これらこれらのような Bison/Yacc の例もチェックしてみてください。Dragon Bookと「Modern Compiler Implementation in C」という本もチェックしてください。

于 2009-11-04T17:39:51.017 に答える