私は最近、スタックベースのプログラミング言語を書く仕事を引き受けました。しかし、自分の言語の設計を始める前に、既存のスタックベースの言語を読んで実験するのは良い考えだと思いました。
これにより、この投稿のトピックに移動します。私は、Postfixスタイルの式を使用するスタックベースの言語であるForthに関するWikipediaの記事を読んでいました。記事では、私は次の声明を見ました:
Forthの柔軟性により、静的なBNF文法が不適切になり、モノリシックコンパイラーがありません。コンパイラを拡張するには、文法を変更して基礎となる実装を変更するのではなく、新しい単語を書くだけで済みます。
私の理解では、フォースの専門用語では、「単語」という用語は基本的に「サブルーチン」と同義のようです。これを考えると、上記のステートメントは奇妙に思えます。Forthで新しい関数を作成する機能がForthの正式な文法を不適切にするのはなぜですか?定義する新しいサブルーチンごとに文法を書き直す必要があるのはなぜですか?環境で新しい単語を書くことは、コンパイラの拡張をどのように構成しますか?上記のステートメントは、新しい関数を定義できるため、正式な文法はPythonには不適切であると言っているように見えます。
実際、私は以下のForthの単純なサブセットに対してBNFスタイルの文法を書くことを試みることにしました。
program ::= stmt+
stmt ::= func | expr
func ::= ':' expr+ ';'
expr ::= INTEGER | word
word ::= ('+' | '-' | '*' | '/' )
上記の文法は、Forthステートメントの有効なサブセットをカバーしているように思われ、Forth言語のすべての有効なステートメントをカバーするように拡張することはそれほど難しくないと思われます。さらに、コンパイラーのパーサーが上記の文法を実装している場合、コンパイラーがどのように拡張されるかはわかりません。コンパイラは、環境に新しい単語を追加するだけです。環境のみが変更されます。まるで、上記のWikipediaからの抜粋は、コンパイラー(変更されない)を構成する下線コードとコンパイラーの環境(変更される)を融合しているようです。
要約すると、なぜ新しい単語(サブルーチン)を定義するForthの能力が、書かれた文法には不適切なのでしょうか。