Я создаю компилятор с Lex и YACC (на самом деле Flex и Bison). Язык допускает неограниченные прямые ссылки на любой символ (например, C #). Проблема в том, что невозможно разобрать язык, не зная, что такое идентификатор.
Единственное известное мне решение состоит в том, чтобы лексировать весь исходный код, а затем выполнить анализ "в ширину", чтобы вещи более высокого уровня, такие как объявления классов и объявления функций, анализировались перед функциями, которые их используют. Однако это заняло бы большой объем памяти для больших файлов, и было бы трудно справиться с YACC (мне пришлось бы создавать отдельные грамматики для каждого типа объявления / тела). Мне также пришлось бы написать лексер (что не так уж и сложно).
Меня не волнует эффективность (хотя это все еще важно), потому что я собираюсь переписать компилятор сам по себе, как только я закончу, но я хочу, чтобы эта версия была быстрой (поэтому, если есть любые быстрые общие методы, которые не могут быть выполнены в Lex / YACC, но могут быть выполнены вручную, пожалуйста, предложите их также). Так что сейчас простота разработки - самый важный фактор.
Есть ли хорошие решения этой проблемы? Как это обычно делается в компиляторах для таких языков, как C # или Java?