А что это вообще такое?

         

Числовые литералы



Запись числовых литералов допускается в следующем виде:

1
-8
(целое)

1.23
-4.56
(дробное)

0xA8 равно 168
(форма шестнадцатиричной записи)

Примечание: регистр букв не важен.









Cache. Сохранение результатов работы кода



^cache[файл](числосекунд){код}
^cache[файл](число секунд){код}{обработчик проблем}   [3.1.2]
^cache[файл][дата устаревания]{код}
^cache[файл][дата устаревания]{код}{обработчик проблем}   [3.1.2]

Оператор сохраняет строку, которая получится в результате работы кода. При последующих вызовах обычно происходит считывание ранее сохраненного результата, вместо повторного вычисления, что сильно экономит время обработки запроса и снижает нагрузку на ваши сервера.

Крайне рекомендуется подключать модули (^use[…]) изнутри кода оператора cache, а не делать это статически (@USE).
По-возможности, работайте с базой данных (^connect[…]) также внутри кода оператора cache - вы существенно снизите нагрузку на ваш SQL-сервер и повысите производительность ваших сайтов.

Файл - имя файла-кеша. Если такой файл существует и не устарел, то его содержимое выдается клиенту, если не существует - выполняется код, и результат сохраняется в файл с указанным именем.

Число секунд - время хранения результата работы кода в секундах. Если это число равно нулю, то результат не сохраняется, а файл с предыдущем сохраненным результатом уничтожается.

Дата устаревания - время, до которого хранится результата работы кода. Если она в прошлом, то результат не сохраняется, а файл с предыдущим сохраненным результатом уничтожается.

Код - код, результат которого будет сохранен.

Обработчик проблем - здесь можно обработать проблему, если она возникнет в коде. В этом отношении оператор похож на try, см. раздел «Обработка ошибок». В отличие от try, можно задать $exception.handled[cache] - это дает указание Parser обработать ошибку особенным образом: достать из файла ранее сохраненный результат работы кода, проигнорировав тот факт, что этот результат устарел.

Внутри кода допустимы команды, изменяющие время хранения результата работы кода:

^cache(число секунд)
^cache[дата устаревания]

Берется минимальное время хранения кода.









Connect. Подключение к базе данных



^connect[строкаподключения]{код}

Оператор connect осуществляет подключение к серверу баз. Код оператора обрабатывается Parser, работая с базой данных в рамках установленного подключения.

Parser (в виде модуля к Apache или IIS) кеширует соединения с SQL-серверами, и повторный запрос на соединение с той же строкой подключения не производится, а соединение берется из кеша, если оно еще действительно.

Вариант CGI также кеширует соединение, но только на один запрос, поэтому явно допустимы конструкции вида:

^connect[строка подключения]{…}
^connect[строка подключения]{…}

При этом не будет двух соединений, и это полезно, когда, скажем, изредка соединение нужно, и заранее неизвестно нужно или нет - заранее его можно не делать, а делать визуально многократно, зная, что оно фактически не разрывается.

Передать SQL-запрос БД может один из следующих методов или конструкторов языка Parser:

table::sql
string:sql
void:sql
hash::sql
int:sql
double:sql

Замечание: для работы оператора connect необходимо наличие настроенного драйвера баз данных (см. раздел Настройка).   

Форматы строки соединения для поддерживаемых серверов баз данных описаны в приложении.









Def. Проверка определенности объекта



Оператор возвращает булевое значение (истина/ложь) и отвечает на вопрос «определен ли объект?» Проверяемым объектом может любой объект Parser: таблица, строка, файл, объект пользовательского класса и т.д.

defобъект   
не определенными (не def) считаются пустая строка, пустая таблица, пустой хеш и код.









Eval. Вычисление математических выражений



^eval(математическоевыражение)  
^eval(математическое выражение)[форматная строка]   

Оператор eval вычисляет математическое выражение и позволяет вывести результат в нужном виде, задаваемом форматной строкой (см. Форматные строки).









-F и -d. Проверка существования файла и каталога



-f имя_файла - проверка существования файла на диске.
-dимя_каталога - проверка существования каталога на диске.   

Возвращает результат "истина/ложь" в зависимости от того, существует ли указанный файл или каталог по заданному пути.









For. Цикл с заданным числом повторов



^for[счетчик](от;до){тело}
^for[счетчик](от;до){тело}[разделитель]
^for[счетчик](от;до){тело}{разделитель}

Оператор for повторяет тело цикла, перебирая значения счетчика от начального значения до конечного. С каждым выполнением тела значение счетчика автоматически увеличивается на 1.

Счетчик - имя переменной, которая является счетчиком цикла

От и до - начальное и конечное значения счетчика, математические выражения, задающие соответственно начало и конец диапазона значений, принимаемых счетчиком. Если конечное значение счетчика меньше начального, тело цикла не выполнится ни разу

Разделитель - код, который выполняется перед каждым непустым не первым телом

Замечание: поскольку имена счетчиков могут повторяться, полезно объявлять их локальными переменными метода, где используется цикл for.   









If. Выбор одного варианта из двух



^if(логическое выражение){код, если значение логического выражения «истина»}
^if(логическое выражение){
   код, если значение логического выражения «истина»
}{
   код, если значение логического выражения «ложь»
}

Оператор вычисляет значение логического выражения. Затем, в зависимости от полученного результата, либо выполняется или не выполняется код (первый вариант использования оператора if), либо для исполнения выбирается код, соответствующий полученному значению логического выражения (второй вариант). На код не накладывается никаких ограничений, в том числе внутри него может содержаться еще один или несколько операторов if.

Внимание: настоятельно советуем задавать комментарии к частям сложного логического выражения (см. «Комментарии к частям выражения»).









In. Проверка, находится ли документ в каталоге



in"/каталог/"    

Возвращает результат "истина/ложь" в зависимости от того, находится ли текщий документ в указанном каталоге.









Is. Проверка типа



объектis тип   

Возвращает результат "истина/ложь" в зависимости от того, относится ли левый операнд к заданному типу.
Полезно использовать этот оператор в случае, если переменная может содержать единственное значение или набор значений (хеш), а также для проверки определенности методов.

Тип - имя типа, им может быть системное имя (hash, junction, …), или имя пользовательского класса.









Изменение времени хранения


^cache[/data/cache/test2](5){
   по ходу работы вы выяснили, 
   что страницу сохранять не нужно: ^cache(0)
}









Комментарии к частям выражения



Допустимо использование комментариев к частям математического выражения, которые начинаются со знака #, и продолжаются до конца строки исходного файла или до конца выражения.









Оператор include


@include[filename][file]
$file[^file::load[text;$filename]]
^process[$caller.self]{^taint[as-is][$file.text]}[
$.file[$filename]
]
Код загружает указанный файл и выполняет его в контексте вызова include. Опция file позволяет указать имя файла, откуда был загружен код. Если возникнет ошибка, вы увидите это «имя файла».









^cache


^cache[/data/cache/test1](5){
   Нажимайте reload, меняется каждые 5 секунд: ^math:random(100)
}

^connect


^connect[mysql://admin:pwd@localhost/p3test]{
   $news[^table::sql{select * from news}]
}

определен ли метод» используйте оператор


$str[Это определенная строка]
^if(def $str){
    Строка определена
}{
    Строка не определена
}

Важно: для проверки «содержит ли переменная код» и « определен ли метод» используйте оператор is, а не def. Таким образом. ^if(def $hash.delete){-}{в hash нет элемента «delete»}.

к частям сложного математического выражения


^eval(100/6)[%.2f]
вернет: 16.67.

Внимание: настоятельно советуем задавать комментарии к частям сложного математического выражения (см. «Комментарии к частям выражения»).

к частям сложного математического выражения.


^if(
    $age>=$MINIMUM_AGE  # не слишком молод
    && $age<=$MAXIMUM_AGE  # и не слишком стар
){
    Годен
}

Внимание: настоятельно советуем задавать комментарии к частям сложного математического выражения. Бывает, что даже вам самим через какое-то время бывает трудно в них разобраться.

Пример выводит ссылки на недели


^for[week](1;4){
   <a href="/news/archive.html?week=$week">Новости за неделю №$week</a>
}[<br>]

Пример выводит ссылки на недели с первой по четвертую, после очередной строки ставится тег перевода строки.

^if(in "/news/")


^if(in "/news/"){
   Мы в разделе новостей
}{
   <a href="/news/">Новости</a>
}

^if(-f "/index.html")


^if(-f "/index.html"){
   Главная страница существует
}{
   Главная страница не существует
}

^switch[$color]


^switch[$color]{
   ^case[red]{Необходимо остановиться и подумать о вечном…}
   ^case[yellow]{Настало время собраться и приготовиться!}
   ^case[green]{Покажи им, кто король дороги!}
   ^case[DEFAULT]{Вы дальтоник, или это вовсе не светофор.}
}

Обращаем ваше внимание на то,


@method[command]
^switch[$command]{
   ^case[add]{
      добавляем…
   }
   ^case[delete]{
      удаляем…
   }
   ^case[DEFAULT]{
      ^throw[bad.command;$command;Wrong command $command, good are add&delete]
   }
}

@main[]
$action[format c:]
^try{
   ^method[$action]
}{
   ^if($exception.type eq bad.command){
      $exception.handled(1)
      Неправильная команда '$exception.source', задана
      в файле $exception.file, в $exception.lineno строке.
   }
}

Результатом работы примера будет
Неправильная команда 'format c:', задана 
в файле c:/parser3tests/www/htdocs/throw.html, в 15 строке.

Обращаем ваше внимание на то, что пользователи вашего сайта не должны увидеть технические подробности в сообщениях об ошибках, тем более содержащие пути к файлам, это некрасиво и ненадежно.
Вывод $exception.file дан в качестве примера и настоятельно не рекомендуется к использованию на промышленных серверах - только для отладки.

в переменной town, будут преобразованы


Пример ^^taint.<br>
$town[Москва]
<a href="town.html?^taint[uri][$town]">$town</a>

В результате данные, хранящиеся в переменной town, будут преобразованы к типу URI. Русские буквы будут заменены на шестнадцатеричные коды символов и представлены в виде %ХХ.

где вам необходимы дополнительные операторы,


Поместите этот код…
@default[a;b]
^if(def $a){$a}{$b}

… в файл operators.p, в корень вашего веб-сайта.

Там, где вам необходимы дополнительные операторы, подключите этот модуль. Например, в корневом auto.p, напишите…
@USE
/operators.p

…теперь не только в любой странице, но, что главное, в любом вашем классе можно будет воспользоваться конструкцией
^default[$form:name;Аноним]

Подробности в разделе Создание методов и пользовательских операторов.

Process. Компиляция и исполнение строки



^process{строка}
^process[контекст]{строка}
^process[контекст]{строка}[опции][3.1.2]

Строка будет скомпилирована и выполнена как код на Parser, в указанном контексте, или в текущем контексте.
В качестве контекста можно указать объект или класс.

Удобно использовать, если какие-то части кода или собственные методы необходимо хранить не в файлах .html, которые обрабатываются Parser, а в каких-то других, или базе данных.

Также можно указать ряд опций (хеш):
·$.main[новое имя для метода main, описанного в коде строки}  
·$.file[имя файла, из которого взята данная строка}  
·$.lineno(номер строки в файле, откуда взята данная строка. может быть отрицательным)  









Простая проверка типа


@main[]
$date[1999-10-10]
#$date[^date::now[]]
^if($date is string){
    ^parse[$date]
}{
    ^print_date[$date.year;$date.month;$date.day]
}

@parse[date_string][date_parts]
$date_parts[^date_string.match[(\d{4})-(\d{2})-(\d{2})][]]
^print_date[$date_parts.1;$date_parts.2;$date_parts.3]

@print_date[year;month;day]
Работаем с датой:<br>
День:  $day<br>
Месяц: $month<br>
Год:   $year<br>

В этом примере в зависимости от типа переменной $date либо выполняется синтаксический анализ строки, либо методу print_date передаются поля объекта класса date:









Простые примеры


^process{@extra[]
   Здоровья прежде всего…
}
Метод extra будет добавлен к текущему классу, и его можно будет вызывать в дальнейшем.

^process[$engine:CLASS]{@start[]
   Мотор…
}
Метод start будет добавлен к пользовательскому классу engine.

$running_man[^man::create[Вася]]
^process[$running_man]{
    Имя: $name<br>
}
Код будет выполнен в контексте объекта $running_man, соответственно, может воспользоваться полем name этого объекта, выдаст «Вася».









Проверка наличия в переменной кода


Т.к. оператор def не считает переменные, содержащие код, определенными, для проверки наличия в переменной кода необходимо использовать is:
$something{^do[]}
^if($somethingis junction){
#   выполнение кода
    $something
}









Проверка определенности метода


Значение $имя_метода, это тоже junction, поэтому проверять существование метода необходимо также оператором is, а не def:
@body[]
тело

@main[]
Старт
^if($body is junction){
   ^body[]
}{
   Метод «body» не определен!
}
Финиш









Rem. Вставка комментария



^rem{комментарий}

Весь код, содержащийся внутри оператора, не будет выполнен. Используется для комментирования блоков кода.









Системное поле объекта: CLASS


$объект.CLASS - хранит ссылку на класс объекта.

Это необходимо при задании контекста компиляции кода (см. «process. Компиляция и исполнение строки».









Сложный пример


Часто удобно поместить компилируемый код в некоторый метод с именем, вычисляющимся по ходу работы:
# это исходный код, обратите внимание, на ^^
$source_code[2*2=^^eval(2*2)]
# по ходу работы выясняется, что необходимо создать метод с именем method1
$method_name[method1]
# компилируем исходный код, помещяем его в новый метод
^process{$source_code}[
   $.main[$method_name]
]

# далее по коду можно вызывать метод method1
^method1[]
Данный пример будет продолжать работать, даже если в $source_code будет определен ряд методов, поскольку опция main задает новое имя методу main.









Создание объекта


^класс::конструктор[параметры]

Конструктор создает объект класса, наделяя его полями и методами класса. Параметры конструкторов подробно описаны в соответствующем разделе.
Примечание: результат работы конструктора - созданный объект, обычный результат работы метода игнорируется (никуда не попадает).









Switch. Выбор одного варианта из нескольких



^switch[строкадля сравнения]{
   ^case[вариант1]{действие для 1}
   ^case[вариант2]{действие для 2}
   ^case[вариант3;вариант 4]{действие для 3 или 4}
         …         
   ^case[DEFAULT]{вариант по умолчанию}
}

^switch(математическое выражение){
   ^case(вариант1){действие для 1}
      ^case(вариант2){действие для 2}
      ^case(вариант3;вариант 4){действие для 3 или 4}
         …         
   ^case[DEFAULT]{вариант по умолчанию}
}

Оператор switch сравнивает строку или результат математического выражения со значениями, перечисленными в case. В случае совпадения выполняется код, соответствующий совпавшему значению. Если совпадений нет, выполняется код, соответствующий значению DEFAULT (пишется только заглавными буквами).

Если код для DEFAULT не определен и нет совпадений со значениями, перечисленными в case, ни один из вариантов кода, присутствующих в операторе switch, выполнен не будет.









Таблицы преобразований


as-is
изменений в тексте не делается

file-spec
символы * ? ' " < > |
преобразуются в "_XX",
где XX - код символа в шестнадцатеричной форме

uri
символы за исключением цифр, строчных и прописных латинских букв, а также следующих символов: _ - . "
преобразуется в %XX где XX - код символа в шестнадцатеричной форме

http-header
то же, что и URI

mail-header
если известен charset (если неизвестен, не будут работать up/low case), то фрагмент, начиная с первой буквы с восьмым битом и до конца строки, будет представлен в подобном виде:
Subject: Re: parser3: =?koi8-r?Q?=D3=C5=CD=C9=CE=C1=D2?=

sql
в зависимости от SQL-сервера
для Oracle/ODBC меняется ' на ''
для PgSQL меняется ' на '' и \ на \\
для MySQL делается средствами самого MySQL

js
" преобразуется в \"
' преобразуется в \' 
\ преобразуется в \\
символ конца строки преобразуется в \n
символ с кодом 0xFF предваряется \

xml
& преобразуется в &amp;
> преобразуется в &gt;
< преобразуется в &lt;
" преобразуется в &quot;
' преобразуется в &apos;

html
& преобразуется в &amp;
> преобразуется в &gt;
< преобразуется в &lt;
" преобразуется в &quot;

optimized-as-is
optimized-xml
optimized-html
дополнительно к заменам выполняется оптимизация по "white spaces" (символы пробела, табуляция, перевода строки).

Идущие подряд перечисленные символы заменяются только одним, который встречается в коде первым
Ряд taint преобразований Parser делает автоматически, так, имена и пути файлов всегда автоматически file-spec преобразуются, и когда вы пишите…

^file::load[filename]

…Parser выполняет…

^file::load[^taint[file-spec][filename]]

Аналогично, при задании HTTP-заголовков и заголовков писем, происходят http-header и mail-header преобразования соответственно. А при DOM-операциях текстовые параметры всех методов автоматически xml преобразуются.

Также Parser выполняет ряд автоматических untaint преобразований:
вид
что преобразуется
sql
тело SQL-запроса
xml
XML код при создании объекта класса xdoc









Throw. Сообщение об ошибке



^throw[type;source]
^throw[type;source;comment]

Оператор throw сообщает об ошибке типа type, произошедшей по вине source, с комментарием comment.

Эта ошибка может быть перехвачена и обработана при помощи оператора try.

Не перехватывайте ошибки только для их красивого вывода, пусть этим централизованно займется метод unhandled_exception, вызываемый Parser если ни одного обработчика ошибки так и не будет найдено. Кроме прочего, произойдет запись в журнал ошибок веб-сервера, который можно регулярно просматривать на предмет имевших место проблем.









Try. Перехват и обработка ошибок



^try{код,ошибки которого попадают…}{…в этот обработчик в виде $exception}

Если по ходу работы кода возникла ошибка, создается переменная $exception, и управление передается обработчику.

$exception, это такой hash:

$exception.type
строка, тип ошибки.
Определен ряд системных типов, также тип ошибки может быть задан в операторе throw.
$exception.source
строка, источник ошибки (ошибочное имя файла, метода, …)
$exception.file
$exception.lineno
$exception.colno
файл, содержащий source,
номера строки и колонки в нем
$exception.comment
комментарий к ошибке, по английски
$exception.handled
истина или ложь, флаг «обработана ли ошибка»
необходимо зажечь этот флаг в обработчике, если вы обработали переданную вам ошибку
Обработчик обязан сообщить Parser, что данную ошибку он обработал, для чего только для нужных типов ошибок он должен зажечь флаг:
$exception.handled(1)

Если обработчик не зажег этого флага, ошибка считается необработанной, и передается следующему обработчику, если он есть.

Если ошибка так и не будет обработана, если есть, вызывается метод unhandled_exception и ему передается информация об ошибке, стек вызовов, приведших к ошибке, и выдаются результаты его работы. А также производится запись в журнал ошибок веб-сервера.








Untaint, taint. Преобразование данных



^untaint{код}
^untaint[вид преобразования]{код}
^taint[текст]
^taint[вид преобразования][текст]

Оператор taint помечает весь переданный ему текст, как нуждающийся в преобразовании заданного вида. Оператор untaint выполняет переданный ему код и помечает, как нуждающиеся в преобразовании, те части результата выполнения кода, которые не являлись частью кода на Parser, а поступили извне, например, из полей формы.

Если вид преобразования не указан, оператор untaint делает преобразование вида as-is, а оператор taint помечает текст как tainted (неопределенно «грязный», без указания вида преобразования).

Само преобразование Parser выполняет позже, при выдаче результата обработки документа пользователю, перед выполнением SQL-запроса или отправкой письма.

Преобразование заключается в замене одних символов на другие в соответствии с внутренними таблицами пребразований. Предусмотрены следующие виды преобразований:

as-is
file-spec
http-header
mail-header
uri
sql
js
xml
html

optimized-as-is
optimized-xml
optimized-html

Выполняемые замены для каждого вида преобразования сведены в таблице ниже.

Важное замечание: «чистый» код также подвергается автоматическому преобразованию. Parser выполняет оптимизацию по «white spaces» (символы пробела, табуляция, перевода строки). Идущие подряд перечисленные символы заменяются только одним, который встречается в коде первым. В общем виде можно представить весь набираемый код следующим образом:

^untaint[optimized-html]{здесьнаходится код, набранный скриптовальщиком}

Необходимо учитывать это при создании кода! Схема автоматического преобразования Parser - optimized-html.   

Пример:

Пример на ^^untaint.<br>
<form>
<input name=field>
<input type=submit>
</form>

$tainted[$form:field]
"Грязные" данные - $tainted<br>
"Чистые" данные - ^untaint{$tainted}

В результате выполнения этого кода поступившие через поля формы данные не будут преобразовываться Parser и выдадутся в том виде, в каком они поступили. В квадратных скобках оператора untaint задается вид выполняемого преобразования. Здесь мы опускаем квадратные скобки в методе untaint и используем параметр по умолчанию [as-is].

Как уже было сказано выше, большую часть работы по преобразованию данных Parser выполняет автоматически. Внешние данные, которые используются в «чистом» коде преобразуются к optimized-html.

Оператор taint также помечает преобразование данных в соответствии с указанной таблицей, но, в отличие от untaint, используется для «чистых» данных, т.е. созданных кодером, либо поступивших извне и уже обработанных untaint. Еще раз обращаем внимание, что преобразование происходит только в момент выдачи данных во внешнюю среду (пользователю, в файл или базу данных). Если не задан вид преобразования, данные останутся "грязными", но никаких замен сделано не будет.









Use. Подключение модулей



^use[файл]

Оператор позволяет использовать модуль из указанного файла. Если путь к файлу начинается с "/", то считается, что это путь от корня веб-пространства. В любом другом случае Parser будет искать модуль по путям, определенным в переменной $CLASS_PATH в Конфигурационном методе.

Для подключения модулей также можно воспользоваться конструкцией:
@USE
имя файла 1
имя файла 2


Разница между этими конструкциями в том, что использование @USE подключает файлы с модулями до начала выполнения кода, в то время как оператор use может быть вызван непосредственно из тела программы, например:

^if(условие){
   ^use[модуль1]
}{
   ^use[модуль2]
}

Замечание: попытки подключить уже подключенные ранее модули не приводят к повторным считываниям файлов с диска. Однако нужно иметь ввиду, что для этого полное имя файла подключаемого модуля должно с точностью до символа совпадать с именем файла уже подключенного ранее модуля. В случае написания ^use[module.p] и ^use[sub/../module.p] будет считаться, что идет попытка подключить разные модули.

Крайне рекомендуем использовать возможность сохранения результатов работы кода, используя оператор use для подключения необходимых модулей в коде оператора cache.









Вызов метода


^объект.метод[параметры]

Вызов метода класса, к которому принадлежит объект. Параметры конструкторов подробно описаны в соответствующем разделе.

Если не указан объект, то конструкция является вызовом метода текущего класса (если у класса нет метода с таким именем, будет вызван метод базового класса) или оператора. При совпадении имен вызывается оператор.

Методы бывают статические и динамические.

Динамическийметод - код выполняется в контексте объекта (экземпляра класса).

Статический метод - код выполняется в контексте самого класса, то есть метод работает не с конкретным объектом класса, а со всем классом (например, классы MAIN, math, mail)









While. Цикл с условием



^while(условие){тело}

Оператор while повторяет тело цикла, пока условие истинно. Если условие заведомо ложно, тело цикла не выполнится ни разу.








Значение поля объекта


$объект.поле

Получение значения поля объекта.









Использование Parser в качестве интерпретатора скриптов



/путь/к/parser3 файл_со_скриптом
x:\путь\к\parser3 файл_со_скриптом

Выполнять скрипты можно и без веб-сервера, достаточно запустить интерпретатор Parser, передав ему в командной строке параметр - имя скрипта. При этом корнем веб-пространства считается текущий каталог.

При этом ошибки попадут в стандартный поток ошибок, который можно перенаправить в желаемый файл так:
команда 2>>error_log
Внимание: не забывайте его время от времени очищать.

На UNIX можно также использовать стандартный подход с заданием команды запуска интерпретатора в первой строке скрипта:
#!/путь/к/parser3
#ваш код
Проверка: ^eval(2*2)
Не забудьте зажечь биты атрибута, разрешающие исполнение владельцу и группе. Команда:
chmod ug+x файл









Конфигурационный файл



Пример файла включен в поставку (см. auto.p.dist).

Этот файл - основной, с которого начинается сборка класса MAIN. Может содержать Конфигурационный метод, который выполняется первым, до метода auto, и задает важные системные параметры.

После выполнения конфигурационного метода можно задать кодировку ответа и кодировку, в которой набран код (по умолчанию в обоих случаях используется кодировка UTF-8):

Рекомендуемый код:
@auto[]
#source/client charsets
$request:charset[windows-1251]
$response:charset[windows-1251]
$response:content-type[
   $.value[text/html]
   $.charset[$response:charset]
]

Примечание: для корректной работы методов upper и lower класса string с национальными языками (в том числе русским) необходимо корректное задание $request:charset.

Также здесь рекомендуется определить путь к классам вашего сайта:
$CLASS_PATH[/../classes]

И строку соединения с SQL-сервером, используемым на вашем сайте (пример для ODBC):
$SQL.connect-string[odbc://DSN=www_mydomain_ru^;UID=user^;PWD=password]
Примечание: вашем коде вы будете использовать ее так:
^connect[$SQL.connect-string]{…} 

Советуем поместить сюда же определение метода unhandled_exception, который будет выводить сообщение о возможных проблемах на вашем сайте.

Внимание: конечно, Конфигурационный файл можно не использовать, а Конфигурационный метод поместить в файл auto.p в корне веб-пространства, однако в разных местах размещения сервера (например: отладочная версия и основной сервер) конфигурации скорее всего будут различными, и очень удобно, когда эти различия находятся в отдельном файле и вне веб-пространства.









Конфигурационный метод



Если в файле определен метод conf,он выполняется первым, до auto, и задает важные системные параметры:
·файлы, описывающие кодировки символов,  
·ограничение на размер HTTP POST-запроса,  
·сервер/программу отправки почты,  
·SQL-драйвера и их параметры,  
·таблицу соответствия расширения имени файла и его mime-типа.  
Рекомендуется поместить этот метод в Конфигурационный файл.

Определение метода:
@conf[filespec]
filespec - полное имя файла, содержащего метод.

Всегда доступна и не нуждается в загрузке файла кодировка UTF-8, являющаяся для Parser кодировкой по умолчанию.
Чтобы сделать доступными для использования Parser другие кодировки, необходимо указать файлы их описывающие, делается это так:
$CHARSETS[
   $.windows-1251[/полный/путь/к/windows-1251.cfg]
   …
]
См. Описание формата файла, описывающего кодировку.

Максимальный размер POST данных:
$LIMITS[
   $.post_max_size(10*0x400*0x400)
]

Параметр отправки писем (см. ^mail:send[…])…

…под Windows и UNIX (под UNIX [3.1.2]) адрес SMTP-сервера
$MAIL[
   $.SMTP[mail.office.design.ru]
]

…под UNIX в safe-mode версиях, настроить программу отправки можно только при сборке Parser из исходных кодов, в бинарных версиях, распространяемых с сайта parser.ru, задана команда
   /usr/sbin/sendmail -i -t -f postmaster
Только в unsafe-mode версиях можно задать программу отправки почты самому:
$MAIL[
   $.sendmail[/custom/mail/sending/program params]
]
и, по умолчанию, используется эта…
   /usr/sbin/sendmail -t -i -f postmaster
…или эта…
   /usr/lib/sendmail -t -i -f postmaster
…команда, в зависимости от вашей системы.
При отправке письма вместо «postmaster» будет подставлен адрес отправителя из письма из обязательного поля заголовка «from».

Также можно задать таблицу SQL-драйверов:
$SQL[
$.drivers[^table::create{protocol driver client
mysql   /full/disk/path/parser3mysql.dll   /full/disk/path/libmySQL.dll
odbc /full/disk/path/parser3odbc.dll
pgsql /full/disk/path/parser3pgsql.dll /full/disk/path/libpq.dll
oracle /path/to/parser3oracle.dll   C:\Oracle\Ora81\BIN\oci.dll?PATH+=^;C:\Oracle\Ora81\bin
}]
]
В колонке client таблицы drivers допустимы параметры клиентской библиотеке, отделяемые знаком ? от имени файла библиотеки, в таком виде:
имя1=значение1&имя2=значение2&…
а также имя+=значение.
Эти переменные будут занесены(=) или добавлены к имеющемуся значению(+=) в программное окружение (environment) перед инициализацией библиотеки. В частности, удобно добавить путь к Oracle библиотекам здесь, если этого не было сделано в системном программном окружении (system environment).

Таблица типов файлов:
#файл, создаваемый ^file::load[…],
#при выдаче в $response:body задаст этот $response:content-type
$MIME-TYPES[^table::create{ext mime-type
zip application/zip
doc application/msword
xls application/vnd.ms-excel
pdf application/pdf
ppt application/powerpoint
rtf application/rtf
gif image/gif
jpg image/jpeg
jpeg image/jpeg
png image/png
tif image/tiff
html text/html
htm text/html
txt text/plain
mts application/metastream
mid audio/midi
midi audio/midi
mp3 audio/mpeg
ram audio/x-pn-realaudio
rpm audio/x-pn-realaudio-plugin
ra audio/x-realaudio
wav audio/x-wav
au audio/basic
mpg video/mpeg
avi video/x-msvideo
mov video/quicktime
swf application/x-shockwave-flash
}]

Расширения имен файлов в таблице должны быть написаны в нижнем регистре. Поиск по таблице нечувствителен к регистру, т.е. файл FACE.GIF получит mime-тип image/gif.









Передача параметров



Параметры могут передаваться в разных скобках и, соответственно, будут по-разному обрабатываться:

(выражение)
- вычисление параметра происходит при каждом обращении к нему внутри вызова метода
[код]
- вычисление параметра происходит один раз перед вызовом метода
{код}
- вычисление происходит при каждом обращении к параметру внутри вызова метода
Пример на различие скобок, в которых передаются параметры:
@main[]
$a(20)
$b(10)
^sum[^eval($a+$b)]
<hr>
^sum{^eval($a+$b)}

@sum[c]
^for[b](100;110){
   $c
}[<br>]

Здесь хорошо видно, что в первом случае код был вычислен один раз перед вызовом метода sum, и методу передался результат кода - число 30. Во втором случае вычисление кода происходило при каждом обращении к параметру, поэтому результат менялся в зависимости от значения счетчика.

Параметров может быть сколь угодно много или не быть совсем. Если в однотипных скобках несколько параметров, то они могут отделяться друг от друга точкой с запятой. Допустимы любые комбинации различных типов параметров.

Например…
    ^if(условие){когда да;когда нет}
…эквивалентно…
    ^if(условие){когда да}{когда нет}









Системные ошибки



type
Пример возникновения
Описание
parser.compile
^test[}
Ошибка компиляции кода. Непарная скобка, и т.п.
parser.runtime
^if(0).
Методу передано неправильное количество параметров или не тех типов, и т.п.
parser.interrupted
Загрузка страницы прервалась (пользователь остановил загрузку страницы или истекло время ожидания)
number.zerodivision
^eval(1/0), ^eval(1\0) или ^eval(1%0)
Деление или остаток от деления на ноль
number.format
^eval(abc*5)
Преобразование к числу нечисловых данных
file.missing
^file:delete[skdfjs.delme]
файл отсутствует
file.access
^table::load[.]
Нет доступа к файлу
image.format
^image::measure[index.html]
Файл изображения имеет неправильный формат (возможно, расширение имени не соответствует содержимому, или файл пуст?)
sql.connect
^connect[mysql://baduser:pass@host/db]{}
Сервер баз данных не может быть найден или временно недоступен
sql.execute
^void:sql{bad select}
Ошибка исполнения SQL запроса
xml
^xdoc::create{<forgot?>}
Ошибочный XML код или операция
smtp.connect
SMTP сервер не может быть найден или временно недоступен
smtp.execute
Ошибка отправки письма по SMTP протоколу
email.format 
Ошибка в email адресе: адрес пустой или содержит неправильные символы
email.send
Ошибка запуска почтовой программы
http.host
^file::load[http://notfound/there]
Сервер не найден
http.connect
^file::load[http://not_accepting/there]
Сервер найден, но не принимает соединение
http.response
^file::load[http://ok/there]
Сервер найден, соединение принял, но выдал некорректный ответ (нет статуса, заголовка)
http.status
^file::load[http://ok/there]
Cервер выдал ответ со статусом не равным 200 (не успешное выполнение запроса)
http.timeout
Загрузка документа с HTTP-сервера не завершилась в отведенное для нее время