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