Lex と YACC (実際には Flex と Bison) でコンパイラを作成しています。この言語では、任意のシンボル (C# など) への無制限の前方参照が可能です。問題は、識別子が何であるかを知らずに言語を解析できないことです。
私が知っている唯一の解決策は、ソース全体を lex してから「幅優先」解析を行うことです。これにより、クラス宣言や関数宣言などのより高いレベルのものは、それらを使用する関数の前に解析されます。ただし、これは大きなファイルの場合に大量のメモリを必要とし、YACC で処理するのは困難です (宣言/本文の種類ごとに個別の文法を作成する必要があります)。また、レクサーを手書きする必要があります (これはそれほど問題ではありません)。
効率についてはあまり気にしません (それでも重要ですが)。これは、完了したらコンパイラ自体を書き直すためですが、そのバージョンを高速にしたいと考えています (高速な一般的なLex/YACC では実行できないが、手動で実行できる手法については、それらも提案してください)。したがって、現時点では、開発の容易さが最も重要な要素です。
この問題に対する良い解決策はありますか? これは通常、C# や Java などの言語のコンパイラでどのように行われますか?