Соответствие команд nroff и HTML, а также их внутреннее представление.
.br BREAKLINE <BR> (LS раз)
.sp argument SPACE <SPACER
type=vertical
size=argument*30>
.bd argument BOLD <B> (Действует на
argument строк)
.ul argument UNDERLINE <U> (Действует на
argument строк)
.cu SUNDERLINE <U> (Действует на
одну строку)
.ce SCENTER <CENTER> (Действует
на одну строку)
.ft argument FONT <FONT
face=argument>
.ps argument SIZE <FONT
size=argument>
.ad argument ADJUST <DIV
align=argument>
.na NOADJUST <PRE>
.fi FILL tFILL=1
.nf NOFILL tFILL=0
.ls argument LINESPACE LS=argument
.ll LINELENGTH Команда поглоща-
ется, но игнорируется
.in argument IN cIN=argument
.ti argument TIN cTIN=argument
.ex EXIT Завершение работы
Описание файлов системы разработки транслятора.
Описание файла nroff2html.lex.
Лексический анализатор lex обрабатывает входной файл. В данном случае производится «механическая» обработка, то есть lex просто распознает лексемы, но не предпринимает никаких действий по отношению к ним, а передает это право yacc’у.
Считывание идет посимвольное, при этом если первый символ в строке не является ‘.’ или символом перевода строки, то строка распознается как текст, то есть в yacc передается соответствующее предупреждение.
Если первый символ в строке – ‘.’, то за ним следует команда. Следующие два символа сравниваются с командами, имеющимися в банке данных, и при идентификации имя опознанной команды передается в yacc. В случае, если команда неизвестна (то есть за точкой идут два символа и пробел либо символ табуляции, но она не совпадает ни с одной из имеющихся в БД), то сама команда поглощается при выводе (не выводится), а текст, к которому эта команда относится, выводится в HTML-файл соответственно с предыдущими установками.
Comarg – аргумент команды. В данной программе различаются четыре варианта аргумента: либо пустой, либо цифровой (darg), либо символьный – единственный символ - (char), либо строка (символ и еще один или несколько символов, кроме пробела и табуляции). Различие символьного и строкового аргумента заключается в особенности lex’а – если какая-то лексема удовлетворяет нескольким правилам, то выбирается то правило, которое представляет лексему большей длины.
В файле есть функция Dlex(T) – выполняющая роль «монитора» при отладке программы.
При компиляции этого файла в результирующий файл будут включены стандартные библиотеки math.h, stdio.h, которые обеспечат поддержку математических операций и стандартного ввода/вывода.
Описание файла nroff2html.yacc.
В этом файле содержится описание действий, сопоставляющихся команде, передаваемой из lex’а.
В начальном разделе этого файла должны быть описаны ВСЕ лексемы-команды, которые могут быть переданы из lex’а.
Помимо этого в файле есть несколько функций.
Dyacc – аналог такой же функции в .lex-файле – выполняет роль «монитора», выдавая дебагговские сообщения при отладке.
Переменные:
c… - счетчики для подсчета строк. Три состояния: -1 – счетчик выключен, >0 – счетчик включен, =0 – счетчик сработал, пора выводить закрывающий тэг.
t… - триггеры, используются при использовании различных шрифтов. Связано с некоторым различием: в nroff вызов нового шрифта автоматически прекращает действие предыдущего, а в HTML необходим закрывающий тэг.
tFILL – есть заполнение или нет
cIN – отступ (число пропусков)
cTIN – временный отступ
Отличие отступа от временного отступа в формате nroff заключается в следующем: временный отступ действует лишь на одну строку и является «вложенным» по отношению к общему отступу. Временный отступ отмеряется от общего и может быть положительным (сдвиг вправо) и отрицательным (сдвиг влево). Счетчику присваивается значение, соответствующее количеству строк, на которое действует правило, а потом идет декрементирование до нуля, когда включается закрывающий тэг. Временный отступ отключается командой .in с нулевым аргументом (то есть отступ равен нулю).
LS – количество строк в пустом пробеле (действует на весь текст). В nroff команда .ls задает пробел между выводимыми строками.
nhtext[YYLMAX] – массив символов. Из lex в yacc передается через yylval(int) – рабочая переменная, в которой хранится значение команды; или через yytext([char]) – хранится то, что взял lex, то есть непосредственно лексема.
$$ - внутренняя псевдопеременная yacc.
Правила в yacc имеют структуру дерева, где корнем является правило list – список строк, описывающий весь входной файл. Далее идет детализация правил, спускаясь к лексемам.
Схема действия проста: lex опознает лексему и передает соответствующую команду в yacc, а далее yacc запрашивает lex на предмет опознания аргумента.
Существует функция breakline – она призвана для реализации команды .ls. Breakline вставляет в результирующий HTML-файл столько тэгов <BR> (перенос строки), сколько было передано в качестве аргумента командой .ls.
Если yacc встречает неизвестную команду, то текст выводится в соответствии с предыдущими настройками, а в поток ошибок выдается соответствующее сообщение.
В файл y.tab.c после компиляции включается в исходном виде все, что в файле nroff2html.yacc заключено между %{ и %} (в разделе объявлений), в том числе файл lex.yy.c, полученный при компиляции nroff2html.lex.
Описание файла nroff2html.c.
nroff2html.c – исходный текст головной программы, при компиляции этого файла образуется исполняемый модуль.
При компиляции включается файл y.tab.c, то есть все вышеперечисленные файлы.
Формат запуска исполняемого модуля таков:
nroff2html input_file output_file
При этом оба аргумента могут быть опушены, и в этом случае роли входного и выходного файлов выполняют соответственно стандартный вход (клавиатура) и стандартный выход (дисплей).
Если же есть аргументы, то программа переходит к имени входного файла и открывает свое устройство (yyin) для чтения. Далее переход ко второму аргументу и открытие соответствующего устройства (yyout) для записи.
Далее в результирующий файл записываются стандартные открывающие тэги для HTML-файла (<HTML>, <HEAD>, <TITLE>, </title>, </head>, <BODY>).
Функция yyparse() обращается к части, образованной из nroff2html.yacc – содержит описание того как yacc обрабатывает файл (включая ошибки). Для получения входных лексем эта функция вызывает функцию лексического анализатора yyerror(). Далее, либо будет обнаружена ошибка и в этом случае (если не задано действий по обработке ошибок) yyparse() вернет 1, либо лексический анализатор вернет конечный маркер и распознаватель завершит обработку возвратом 0.
По окончании отработки своего функцией yyparse(), программа nroff2html.c вписывает закрывающие основные тэги HTML-файла: </body> и </html>.
Описание файла y.output.
Этот файл подробно показывает КАК реально все выполняется и когда какое правило применяется. Файл представляет из себя набор состояний для yacc’а. При этом показывается какие правила и как в этих состояниях выполняются.
Поясню лишь некоторые функции:
goto – безусловный переход к состоянию.
reduce i – заносит текущее состояние в стек и переход к i.
shift – замена состояния в стеке.
Строка $accept : _list $end – означает взять весь файл.
Описание команд.
SPACE .sp - (с аргументом) SPACER
LINESPACE .ls - (с аргументом) определяет LS, используется при выводе разрывов строки в HTML.
BOLD .bd - (с аргументом) включает триггер, вставляет <B>, включает счетчик.
UNDERLINE .ul - аналогично с BOLD
SUNDERLINE .cu - (без аргумента) подчеркнуть одну строку. Счетчик = 1.
SCENTER .ce - (без аргумента) Центрирование одной строки. Счетчик = 1.
BREAKLINE .br - вызывается функция вставки breakline, если LS, то соответствующее число раз.
FONT .ft - (с аргументом) если триггер включен, то закрывает существующий font, выводит тэг <FONT face= “имя_аргумента”.
SIZE .ps - аналогично с FONT, но передает размер.
ADJUST .ad - если включен триггер преформатирования, то она его отключает, если было другое форматирование – отключаем его, включаем триггер, тэг <DIV align= соответствующее_выравнивание.
NOADJUST .na - дальше идет уже отформатированный текст. Отключаются предыдущие установки.
LINELENGTH .ll - обрабатывается (берется), но просто игнорируется, так как в HTML в отличие от nroff существует горизонтальная полоса прокрутки.
IN .in - отступ
TIN .ti - временный отступ
FILL .fi - заполнение (растягивание текста от края до края). Если уже есть ADJUST, то FILL игнорируется.
NOFILL .nf - отключает FILL.
UNKNOW - неизвестная команда.
EXIT .ex - возвращает 0 (завершает работу).
Определение команд для HTML-файла.
SPACE - вставка свободного пространства. Используется команда SPACER – высота пробела высчитывается по формуле: количество_строк*30, так как в spacer передается в качестве аргумента количество пикселей.
LINESPACE - определяет переменную LS.
BOLD - для соответствующего текста вставляет тэг <B>.
UNDERLINE - для соответствующего текста вставляет тэг <U>.
SUNDERLINE - для соответствующего текста вставляет тэг <U>.
Примечание: эти две команды аналогичны, но в SUNDERLINE действие производится лишь над одной строкой.
SCENTER - для соответствующего текста вставляет тэг <CENTER>.
BREAKLINE - вызывает функцию breakline.
FONT - если уже было открытие какого-то шрифта, то сначала вставляет тэг </font>, затем для соответствующего текста вставляет тэг <FONT face=имя_аргумента>.
SIZE - так же как и FONT, но в качестве аргумента передается не имя шрифта, а его размер.
ADJUST - если уже было открыто преформатирование или выравнивание, то сначала оно закрывается соответствующими тэгами (</pre>, </div>), а затем для соответствующего текста вставляет тэг <DIV align=соответствующий_тип_выравнивания>
NOADJUST - если уже было открыто преформатирование или выравнивание, то сначала оно закрывается соответствующими тэгами (</pre>, </div>), а затем для соответствующего текста вставляет тэг <PRE>.
LINELENGTH - игнорируется, благодаря горизонтальной полосе прокрутки, существующей в браузерах.
IN - соответствующей переменной присваивается значение, передаваемое аргументом.
TIN - соответствующей переменной присваивается значение, передаваемое аргументом.
FILL - соответствующей переменной присваивается значение 1.