В данном разделе будут рассмотрены исходные тексты, лежащие в каталоге src
дистрибутива Рефала-05.
Компилятор построен как набор повторно используемых компонент: синтаксического дерева, лексического и синтаксического анализаторов, генератора кода и набора утилитарных функций. Эти компоненты можно использовать как библиотеки при написании других инструментальных средств для работы с Рефалом-05. Мотивация такого подхода описана в первом разделе.
Все компоненты, рассматриваемые здесь, написаны на общем подмножестве Рефала-05
и Рефала-5, а это значит, что их можно использовать и при программировании
на Рефале-5 тоже. Более того, если для раскрутки компилятора использовался
Рефал-5, то скомпилированные .rsl
-ки рассматриваемых библиотек лежат в папке
bin
, а это значит, что её можно добавить в переменную REF5RSL
. Об этом
говорилось в разделе установки, но повторить лишним
не будет.
Интерфейс рассматриваемых библиотек может меняться в будущих версиях, что не всегда будет вовремя отражаться в документации. Поэтому сверяйтесь с комментариями в исходных текстах.
R05-CompilerUtils
Компонент зависит от LibraryEx
.
Данный компонент содержит несколько функций, упрощающих написание инструментальных средств, совместимых по поведению с Рефалом-05.
R05-LoadPath
<R05-LoadPath> == e.Folders
e.Folders ::= (e.Folder)*
e.Folder ::= s.CHAR+
Функция возвращает пути поиска, заданные в переменных окружения R05PATH
и REF5RSL
.
R05-FindFiles-Default
и R05-FindFiles
<R05-FindFiles-Default e.Files> == t.FoundFile*
<R05-FindFiles (e.Folders) e.Files> == t.FoundFile*
e.Files ::= (e.FileName)*
t.FoundFile ::=
(Source (e.Source) e.Output)
| (Output e.Output)
| (NotFound e.FileName)
e.Source, e.Output, e.FileName ::= s.CHAR+
Функции производят поиск указанных файлов в каталогах поиска. Первая функция
R05-FindFiles-Default
осуществляет поиск в каталогах по умолчанию, возвращаемых
функцией R05-LoadPath
. Вторая функция осуществляет поиск в каталогах,
указанных пользователем.
R05-CCompile
<R05-CCompile e.CSources> == e.RetCode
e.CSources ::= (s.CHAR* '.c')*
e.RetCode ::= '-'? s.NUMBER
Выполняет компиляцию исходных текстов на Си компилятором, заданным в переменной
окружения R05CCOMP
, с флагами, заданными в R05CFLAGS
. Функция автоматически
добавляет к командной строке компилятора каталоги, возвращаемые функцией
R05-LoadPath
как каталоги поиска заголовочных файлов (используется опция
-Iкаталог
).
Если переменная R05CCOMP
установлена и непустая, то возвращаемое значение
функции совпадает с возвращаемым значением функции System
, при помощи которой
активируется командная строка.
Если переменная R05CCOMP
не установлена или пустая, то возвращаемое значение
всегда 0
.
R05-Generator
В этом компоненте всего две похожие функции
<R05-Generate-ToFile (e.OutputFile) e.Tree> == пусто
(использует SaveFile → файл № 39)
<R05-Generate-ToLines e.Tree> == (s.CHAR*)*
Обе функции принимают синтаксическое дерево и формируют код на Си. Первая
функция записывает исходный текст в файл (используя SaveFile
, т.е. файл № 39),
вторая возвращает сгенерированный текст как последовательность строк.
R05-Parser
В этом компоненте три похожие функции:
<R05-Parse-File e.SourceFile>
== Success e.Tree
== Fails e.Errors
e.Errors ::= ((s.Row s.Col) e.Message)*
Функция выполняет синтаксический анализ указанного источника, и, если не было синтаксических ошибок, возвращает дерево, в противном случае возвращает список ошибок.
<R05-PrepareAST e.Refal5-AST>
== Success e.R05-AST
== Fails e.Errors
Функция преобразует e.Refal5-AST
(определено
в refal-5-framework/R5FW-Parser-Defs.md) в синтаксическое дерево
Рефала-05, в частности, раскрывает псевдокомментарии *$ENUM
, *$EENUM
и *$EXTERN
и выполняет дополнительные семантические проверки.
refal05c
Формально он не предназначен для повторного использования, как остальные
компоненты — он содержит функцию $ENTRY Go
и связывает рассмотренные выше
библиотеки в единое целое.
Но, при желании, его можно использовать как компонент, подменив зависимые
компоненты на альтернативные компоненты с тем же интерфейсом. Например,
если реализовать в собственном коде функцию R05-Generate-ToFile
, то можно
собрать компилятор с альтернативным кодогенератором.
Однако, этот способ использования не поддерживается и не рекомендуется.