いくつかのコンパイラの本/記事/論文は、文法の設計とその演算子の結合性の関係について語っています。私はトップダウン、特に再帰降下パーサーの大ファンであり、これまでに書いたほとんどの (すべてではないにしても) コンパイラーは、次の式の文法を使用しています。
Expr ::= Term { ( "+" | "-" ) Term }
Term ::= Factor { ( "*" | "/" ) Factor }
Factor ::= INTEGER | "(" Expr ")"
これは、この BNF の EBNF 表現です。
Expr ::= Term Expr'
Expr' ::= ( "+" | "-" ) Term Expr' | ε
Term ::= Factor Term'
Term' ::= ( "*" | "/" ) Factor Term' | ε
Factor = INTEGER | "(" Expr ")"
私が読んだことによると、演算子の結合性 (これらの 4 つの演算子は左から右) の変更により、この文法が「間違っている」と見なす人もいます。これは、解析ツリーが左ではなく右に成長することによって証明されています。属性文法を介して実装されたパーサーの場合、l-attribute 値ではこの値が最初に作成されてから子ノードに渡される必要があるため、これは当てはまります。ただし、通常の再帰降下パーサーで実装する場合、最初にこのノードを構築してから子ノードに渡す (トップダウン) か、最初に子ノードを作成してから、戻り値をこのノードの子として追加する (渡される) かは私次第です。このノードのコンストラクターで) (ボトムアップ)。この文法が「間違っている」という声明に同意しないため、ここで見逃しているものがあるはずです この文法は多くの言語で使用されています。ワーシアンのもの。通常 (またはすべて?) LL ではなく LR 解析を促進するという読み方です。