Смекни!
smekni.com

Разработка конвертора из текстового формата nroff в гипертекстовый формат HTML (стр. 9 из 13)

Соответствие команд 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.