remix (1119427), страница 5
Текст из файла (страница 5)
Традиционные преимущества таких языков — компилируемость, высокая эффективность разработанных программ,возможность управления любыми системными ресурсам — перестают бытьтаковыми для CGI-программ. Шлюзовым программам не обязательно бытьмаксимально эффективными, так как основное время тратится не на выполнение программы генерации HTML-текста, а на передачу его по медленным(относительно процессора) сетевым каналам связи. Доступ к системным ресурсам для программ, запуск которых инициируется извне (по HTTP-запросуот веб-клиентов), должен быть не упрощен, а наоборот ограничен. Удобстворазработки шлюзовых программ является более важным требованием к соответствующей системе программирования нежели эффективность получаемого кода.Ниже описаны три варианта модельных языков, предлагаемых длявстраивания в реализованный веб-сервер.
Каждый из вариантов отвечаетминимальным требованиям к языкам для написания CGI-программ, а именно:— достаточно полный набор операторов, включающий в себя присваивание, ветвление на 2 варианта (if-then-else), циклы (while-do,do-while, for), составной оператор;— как минимум, два типа данных: целый с базовыми арифметическимиоперациями и строковый с операцией конкатенации;— набор стандартных функций, включающий в себя доступ к переменным окружения, базовые функции обработки строк и символьный ввод/вывод.Кроме того, каждый из языков должен поддерживать хотя бы один изспособов встраивания в веб-сервер.25Методические указания по выполнению третьего этапа задания6.1.
Способы встраиванияпрограмм на модельныхязыках в веб-серверМы рассмотрим три способа встраивания программ:— базовый.— внутристраничный тег «<? ?>».— внутристраничный тег SCRIPT.В базовом способе программа из GET-запроса, обрабатываемая интерпретатором модельного языка — это просто текст на этом языке, генерирующий в стандартный канал вывода HTML-страницу, которая и выдаетсякак ответ веб-сервера.
Именно такой способ мы применяли в примере дляязыка Си (правда, без интерпретатора). Этот способ — самый простой, и онприменим к любой CGI-программе. Однако он является не самым удобнымдля разработчика.При внутристраничном способе встраивания программа изGET-запроса представляет собой HTML-текст, в который встроены фрагменты CGI-программы. Интерпретатор такой программы должен различатьHTML-текст и код CGI-программы. HTML-текст просто выводится в стандартный канал, а фрагменты программы выполняются сразу после их считывания из текста файла. В этом случае надо писать фрагменты, генерирующие только изменяющиеся части страницы, а постоянные части можносразу оформлять как HTML-текст.
В результате общий объемCGI-программы существенно уменьшается (как и усилия по ее написанию ипониманию).Разумеется, фрагменты CGI-программы должны четко выделятьсясинтаксически, а соответствующий интерпретатор должен уметь различатьHTML-текст и собственно программу. Удобно включать фрагменты программы внутрь специальных тегов. При втором способе встраивания используется тег «<? ?>», который не входит в HTML. Части программы размещаются между открывающим «<?» и закрывающим «?>» тегами.Например, текст на языке PHP, выводящий тот же текст, что и в предыдущем примере на Си, выглядит так:Content-type: text/html<html><body>Приветствую! Вы ввели аргументы:<? echo "$QUERY_STRING с адреса $REMOTE_ADDR" ?><body></html>Здесь фрагмент программы на PHP содержит оператор вывода echo.
Всеостальное — это просто HTML-текст.При третьем способе используется стандартный HTML-тег SCRIPT.Этот тег используется для встраивания исполняемых программ в любыеHTML-страницы, причем выполняться эти программы могут как сервером(для генерации содержимого страницы), так и клиентом-браузером. Нас будет интересовать только первый вариант.26Методические указания по выполнению третьего этапа заданияТег SCRIPT имеет следующий вид:<script language="lang_name" runat="server">текст программы</script>Атрибут LANGUAGE содержит имя языка (в общем случае могут поддерживаться разные языки) — по умолчанию это JavaScript.
АтрибутRUNAT="server" сообщает интерпретатору о том, что соответствующийфрагмент должен выполняться на сервере, а не на клиенте. Заметим, что поумолчанию этот атрибут соответствует клиенту, поэтому при отсутствииатрибута RUNAT интерпретатор обязан выводить весь тег SCRIPT в томвиде, как он есть, в стандартный вывод (для последующей обработки клиентом).Приведем пример программы на модельном JavaScript, который генерирует ту же самую страницу, что и в предыдущих примерах:<html><body>Приветствую! Вы ввели аргументы:<script language="lang_name" runat="server">Response.write( "Приветствую! Вы ввели аргументы: " +Environment["QUERY_STRING"] + "с адреса " +Environment["REMOTE_ADDR"]);</script><body></html>Также как и в примере на PHP, фрагмент программы на JavaScript содержит обращение к функции вывода (только она называется write и являетсяметодом объекта Response).
Весь остальной текст — это HTML.Разумеется, внутристраничные методы встраивания доставляют дополнительные «заботы» интерпретатору: ведь он должен анализировать нетолько текст на «своем» языке, но и HTML-текст. При этом «родной» текстдолжен быть проанализирован, переведен в промежуточное представление(например, разновидность ПОЛИЗ [5]) и выполнен (интерпретирован). Всвою очередь, HTML-текст должен быть просто перенаправлен на стандартный вывод, поэтому требования к анализу и обработке HTML-текстасущественно ниже.
Интерпретатор должен вычленить текст программы ивыполнить его, весь остальной текст — перенаправить. Обработка возможных ошибок в HTML, проверка корректности и возможности отображенияHTML-текста — задача других инструментов.6.2. Описание модельных языковДля описания модельных языков используются следующие соглашения иобозначения (традиционные для расширенной БНФ):— запись вида {α} означает итерацию цепочки α, т.е.
цепочки вида: ε, α,αα, ααα и т.д.;27Методические указания по выполнению третьего этапа задания— запись вида [α] означает: α или «пусто» (ε);— для отличия метасимволов БНФ (фигурных и квадратных скобок,а также вертикальной черты) от терминальных символов модельныхязыков они выделены красным шрифтом (например, {}, [ ], |);— служебные (ключевые) слова модельных языков выделены жирнымшрифтом (for)6.2.3 Модельный языкпрограммированияВ качестве первого варианта языка предлагается использовать модельныйязык программирования из задания практикума, разработанногоТ. В.
Руденко [6]. Единственное (и обязательное) расширение этого языка,необходимое для использования в CGI-технологии, это добавление специальных переменных для доступа к переменным окружения. Эти переменныеимеют вид: $Name, где идентификатор Name — это имя переменной окружения (например, $QUERY_STRING). Все переменные окружения имеют типstring. Они могут появляться везде в выражениях строкового типа, но ихзначение не может быть изменено. Заметим, что в задании не определенсинтаксис понятия идентификатор. Однако для наших целей имя (идентификатор) переменной окружения должно быть совместимо с требованиямиОС UNIX, поэтому будем требовать, чтобы в идентификатор (по-крайнеймере для имен переменных окружения) могли входить латинские буквы,цифры и символ подчеркивания «_».
Регистр букв имеет значение.Модельный язык должен поддерживать единственный способ встраивания — внешний (внутристраничные не используются).6.2.4 Модельный JavaScript (MJS)Второй вариант модельного языка основан на языке JavaScript [7].6.2.4.1. ПеременныеМы ссылаемся на переменные с помощью имен (идентификаторов). Имя —это последовательность латинских букв, цифр и знаков подчеркивания («_»).Регистр букв имеет значение (A и a — это разные идентификаторы).
Имя неможет совпадать ни с одним из служебных слов (регистр букв в служебныхсловах также имеет значение — он всегда нижний).Важнейшей особенностью языка MJS является динамическая типизацияпеременных, что означает, что переменная может иметь значение любоготипа. Тип значения определяется при присваивании или инициализации переменной и может измениться при последующих присваиваниях.
Поэтомунеобходимость в явном объявлении переменных отпадает, и в «родном»языке JavaScript переменные можно не объявлять. Не объявленная явно переменная начинает существовать с момента первого присвоения ей значения.Однако такая практика ухудшает как эффективность, так и надежность программного кода, поэтому в модельном варианте переменные необходимоявно объявить до первого использования с помощью служебного слова var,например:28Методические указания по выполнению третьего этапа заданияvar x = "string value";var Y;Такое объявление (а точнее — определение) может появиться везде, гдеможет появиться оператор (оно и является частным случаем оператора).С понятием переменной связано понятие «область действия».
Если переменная объявлена на верхнем уровне программы (т.е. непосредственновнутри какого-либо тега SCRIPT), то она является глобальной и ее областьдействия — вся программа (начиная с точки объявления). В противном случае переменная локальна и ее область действия — блок, где появилось ееобъявление. После выхода из блока локальные переменные перестают существовать.6.2.4.2.
Простые типы данных и операцииВ MJS есть 3 простых типа данных: строковый (String), числовой (Number)и логический (Boolean).Константы строкового типа данных содержат любые символы, заключенные в двойные кавычки ("Пример строки"), либо в одинарные кавычки('Еще один пример строки'). Если в тексте константы нужно указать кавычку,то она предваряется экранирующим символом «\» ("Пример строки с кавычками:\", \' ") . Если в тексте нужно указать экранирующий символ, то ондублируется («\\»).Операции над строковым типом включают в себя конкатенацию (+) ишесть операций сравнения (==, !=, <, >, <=, >=).
Используется обычное лексикографическое сравнение строк.Числовой тип данных содержит как целые, так и вещественные значения. Для записи целочисленных констант используется десятичное представление (124, −13 и т.д.). Для записи вещественных констант используетсялибо представление с дробной частью, отделенной точкой (12.345), либопреставление в виде «мантисса-порядок» (1.2E2, −0.5e−3). Используется десятичное представление, порядок отделяется латинской буквой E (e).Операции над числовым типом включают в себя арифметические,операции сравнения, инкрементные и декрементные.Арифметические операции традиционны: +, −, *, /, а также остаток отделения (%).