Процесс анализа верхнего уровня
 

fb.bas:fbCompile()вызывается из FBC интерфейса для каждого входного файла. Разбор (и компиляция) файла начинается здесь.

fb.bas:fbCompile()
  • Открывает входной .bas
  • Запуск выпуска (ir) (открывает выходной .asm)
  • fbMainBegin() (Построение AST для неявного main() или статический конструктор для кода на уровне модуля)
  • fbPreIncludes()
    • fbIncludeFile() для каждого нового включения (ищется в командной строке FBC)
  • cProgram()
  • fbMainEnd() (Закрывает неявный main())
  • Закрытие выпуска (ir) (Конец генерации .asm и закрытие его)
  • Закрытие входного .bas

fb.bas:fbIncludeFile()
  • Поиск включаемого файла
  • lexPush() (Заталкивает (Push) новый контекст лексера включаемого файла в парсер , не нарушая состояния лексера в родительском файле)
  • Открывает включаемый файл
  • cProgram()
  • Закрывает включаемый файл
  • lexPop() (Восстановление состояния лексера в родительском файле)

parser-toplevel.bas:cProgram() является корнем FB грамматики, и парсит файл. Вот кратко и том, что делается:
  • cLine() несколько раз, пока EOF
    • cLabel()
    • cStatement()
      • Декларации
        • UDT декларации, определения типов
        • Переменные (DIM, VAR, ...)
        • Декларации процедур (DECLARE)
        • Тело процедур (SUB, FUNCTION, ...)
(Procs временно заменяет неявную процедуру на уровне модуля, поэтому любые AST узлы входят в них вместо неявной main())
      • Соединения заявлений (IF/ELSE, DO/LOOP, EXIT/CONTINUE DO, ...)
      • Вызовы процедур
      • Результат задания функции
      • Устаревшие заявления (специальные QB rtlib/gfxlib заявления)
      • ASM блоки
      • Присвоения
      • Вызовы указателя процедуры

и большинство из них используют cExpression() в некоторой точке.