Выражения фильтра посылок

Содержание

  1. Типы данных
  2. Статусы посылок
  3. Преобразования типов
  4. Примитивы доступа к базе посылок
  5. Другие примитивы
  6. Приоритеты операций
  7. Операции
  8. Примеры

Выражение фильтра посылок позволяет задать условия, которым должны удовлетворять параметры посылок, чтобы быть показанными в списке посылок, генерируемом CGI-программами new-master и new-judge. Выражение фильтра должно иметь тип bool, а в противном случае генерируется ошибка.

При генерации страницы привилегированного пользователя в CGI-программах new-judge или new-master выражение фильтра используется следующим образом. Выражение фильтра применяется ко всем записям в базе посылок, и если на некоторой записи результат вычисления выражения равен true, то данная запись помечается как удовлетворяющая фильтру. Если при вычислении выражения фильтра хотя бы для одной посылки возникла ошибка, отображается информация об ошибке, а не результаты фильтрации. Если при вычислении выражения фильтра для всех записей завершилось успешно, из записей, удовлетворяющих выражению фильтра, отображаются записи в соответствии с заданным номером первой и номером последней записей.

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

Типы данных

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

Статусы посылок

OK OK
CE Compilation error
RT Run-time error
TL Time-limit exceeded
PE Presentation error
WA Wrong answer
CF Check failed (internal error)
PT Partial solution
AC Accepted
IG Ignored
DQ Disqualified
PD Pending
ML Memory-limit error
SE Security violation
SY Synchronization error
SV Style violation
WT Wall time (real time) limit exceeded
PR Pending review
SM Summoned for defence
RJ Rejected
RU Running (in testing queue or being tested)
CD Compiled (but not yet running)
CG Compiling (in compile queue or being compiled)
AV Available for testing
EM Empty record
VS Virtual start
VT Virtual stop

Преобразования типов

Выражение фильтра посылок строго типизировано, но для преобразований значений одного типа в значения другого типа могут использоваться операции преобразования типа. Операция преобразования типа записывается в стиле Си++, то есть следующим образом:

type-cast-op = type-name "(" expr ")"
Здесь type-name — имя типа, одно из перечисленных выше bool, int, string, date_t, dur_t, size_t, result_t, hash_t, ip_t. Не все возможные преобразования типов допустимы. Возможные комбинации исходного типа и целевого типа показаны в таблице ниже. В строках таблицы записан исходный тип, а в столбцах таблицы — целевой тип.

  bool int string date_t dur_t size_t result_t hash_t ip_t
bool + + +
int + + + + + + + +
string + + + + + + + + +
date_t + + + +
dur_t + + + +
size_t + + + +
result_t + + + +
hash_t + + + +
ip_t + + + +

Рассмотрим подробнее каждое нетривиальное преобразование типов.

Примитивы доступа к базе посылок

Текущей посылкой назовём обрабатываемую при вычислении выражения фильтра посылку. На основании результата вычисления выражения фильтра определяется, может ли быть отображена текущая посылка.

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

f [ ( expr ) ]
Здесь в квадратных скобках [ и ] записана необязательная часть. Круглые скобки ( и ) обозначают сами себя. \V{f} — это имя примитива, а expr — это выражение целого типа. Если выражение в скобках не задано, то берётся значение поля, соответствующего имени примитива f, текущей посылки. Если выражение в скобках не является выражением целого типа, генерируется ошибка. В противном случае выражение вычисляется, и пусть при вычислении выражения ошибок не возникло, а n — результат вычисления выражения.

Если n < 0, то n задаёт номер посылки начиная от последней, то есть n' = N + n$, где N — общее количество посылок в базе посылок в данный момент. В противном случае предполагаем, что n задаёт номер посылки начиная от нулевой, то есть n' = n. Если теперь n' < 0 или n' ≥ N, то генерируется ошибка вычисления выражения фильтра. Если же n' удовлетворяет ограничениям, берётся значение поля, соответствующего имени примитива f, в посылке с номером n'.

Примитивы доступа к базе посылок перечислены в таблице.

Имя примитива Тип значения Описание
id или run_id int Номер посылки (значение поля run_id). Посылки нумеруются от 0.
time time_t Астрономическое время получения посылки сервером (значение поля time)
dur dur_t Длительность времени от начала турнира до получения посылки сервером (то есть разность между временем получения посылки и моментом начала турнира)
size size_t Размер исходного текста программы в байтах (значение поля size).
hash hash_t Хэш-код текста программы (значение поля sha1).
uuid string Уникальный идентификатор посылки (значение поля run_uuid).
ip ip_t IP-адрес клиента, на котором работает веб-браузер, и с которого была получена данная посылка (значение поля ip).
uid или user_id int Идентификатор пользователя, от имени которого была выполнена данная посылка (значение поля user_id). Идентификатор пользователя всегда больше нуля.
login string Регистрационное имя (login) пользователя, от имени которого была выполнена данная посылка.
name string Имя (name) пользователя, от имени которого была выполнена данная посылка.
group string Группа первого участника пользователя, от имени которого была выполнена данная посылка.
cypher string Шифр пользователя, от имени которого была выполнена данная посылка.
lang или lang_id string Короткое имя языка программирования, который был использован в данной посылке. Идентификатор языка программирования находится в поле lang_id записи базы посылок, а короткое имя языка программирования берётся из значения конфигурационной переменной short_name секции описания языка программирования файла конфигурации турнира serve.cfg.
arch string Архитектура языка программирования
prob или prob_id string Короткое имя задачи, решаемой в данной посылке. Идентификатор задачи находится в поле prob_id записи базы посылок, а короткое имя задачи берётся из значения конфигурационной переменной short_name секции описания задачи файла конфигурации турнира serve.cfg.
result или status result_t Статус посылки (значение поля status).
score int Балл за данную посылку без учёта штрафных баллов за посылки (значение поля score).
test int Минимальный номер теста, на котором программа дала неверный результат, или количество успешно пройденных тестов в зависимости от типа турнира.
imported bool Флаг импортированной посылки (значение поля is_imported).
hidden bool Флаг скрытой посылки (значение поля is_hidden).
readonly bool Флаг неизменяемой посылки (значение поля is_readonly).
variant int Действительный вариант. Если для вариантной задачи номер варианта, хранящийся в базе посылок (значение поля variant), равен 0, используется номер варианта, установленный в файле карты вариантов, устанавливаемом глобальной конфигурационной переменной variant_map_file конфигурационного файла описания турнира serve.cfg.
rawvariant int Хранимый вариант задачи в посылке (значение поля variant).
userinvisible bool true, если посылка выполнена пользователем, у которого установлен статус invisible.
userbanned bool true, если посылка выполнена пользователем, у которого установлен статус banned.
userlocked bool true, если посылка выполнена пользователем, у которого установлен статус locked.
userincomplete bool true, если посылка выполнена пользователем, у которого установлен статус incomplete.
userdisqualified bool true, если посылка выполнена пользователем, у которого установлен статус disqualified.
latest bool true, если посылка имеет статус OK, Partial solution или Accepted for testing и после нее нет посылок того же пользователя по той же задаче с этими статусами. Предикат может применяться в турнирах типа Olympiad для отбора посылок для полной проверки.
afterok bool true, если у этого пользователя уже была посылка по этой же задаче, которая получила статус OK
judge_id int Идентификационный номер запроса на тестирование (поле judge_id). Идентификационный номер изменяется в диапазоне от 1 до 65535. Число 0 означает отсутствие идентификационного номера.
inusergroup(GRP) bool true, если этот пользователь принадлежит указанной группе пользователей. Название группы пользователей записывается как строка. Пример: inusergroup("Group1").

Другие примитивы

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

p
где p — это имя примитива. Примитивы перечислены в таблице.

Имя примитива Тип значения Описание
now time_t Текущее астрономическое время.
start time_t Астрономическое время начала турнира.
finish time_t Астрономическое время завершения турнира.
total int Общее количество записей в базе посылок.

Приоритеты операций

В данном разделе перечислены все операции, допустимые в выражении фильтра. Операции перечисляются в порядке убывания приоритета от наиболее приоритетных к наименее приоритетным. Приоритеты операций совпадают с приоритетами операций в языках Си, Си++, Java.

  1. Все литеральные значения (булевские, целые, строковые, статусные), все примитивы, операции преобразования типа, операция записи выражения в скобках (expr).
  2. Префиксные операции ~, !, -, +. Префиксные операции читаются справа налево.
  3. Мультипликативные операции *, /, %. Мультипликативные операции левоассоциативны, то есть читаются слева направо.
  4. Аддитивные операции +, -. Они читаются также слева направо.
  5. Операции сдвига << и >>. Читаются слева направо.
  6. Операции отношений ==, !=, <, >, <=, >=, ~=. Читаются слева направо.
  7. Операция побитового «и» &. Читается слева направо.
  8. Операция побитового исключающего «или» ^. Читается слева направо.
  9. Операция побитового «или» |. Читается слева направо.
  10. Операция логического «и» && или and (эти формы записи синонимичны). Читается слева направо.
  11. Операция логического «или» || или or (эти формы записи синонимичны). Читается слева направо.

Далее рассмотрим все перечисленные операции.

Операции

Операция побитового отрицания ~

Операция применима только к значению типа int. Результат операции — значение типа int, получаемое побитовым отрицанием первого значения.

Операция логического отрицания !

Операция применима только к значению типа bool. Результат операции — значение типа bool, получаемое логическим отрицанием исходного значения.

Операция смены знака -

Унарная операция смены знака применима только к значению типа int. Результат операции — значение типа int с противоположным знаком. Если результат операции не представим в типе int (то есть 32-битным знаковым числом), диагностируется ошибка переполнения.

«Пустая» операция +

Данная операция применима только к значению типа int и даёт результат типа int. Результирующее значение равно исходному.

Операция умножения *

Для операции умножения возможны следующие комбинации типов операндов.

Операция целочисленного деления /

Для операции целочисленного деления возможны следующие комбинации типов операндов. Если делитель равен нулю, диагностируется ошибка деления на ноль. Если результат операции не представим в типе результата, диагностируется ошибка переполнения. Например, при делении минимального значения типа int, равного −231 на −1 получается значение 231, не представимое в типе int.

Операция взятия остатка от деления %

Операция взятия остатка поддерживает несколько комбинаций типов аргументов. Если делитель равен нулю, диагностируется ошибка деления на ноль. Если тип делителя — какой-либо знаковый тип (например, int или dur_t), и делитель отрицателен, диагностируется ошибка неверного аргумента. Если результат операции не представим в типе результата, диагностируется ошибка переполнения. Допустимые комбинации типов операндов перечислены ниже.

Операция сложения +

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

Операция вычитания -

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

Операции сдвига << и >>

Операции побитового сдвига влево << и побитового сдвига вправо >> применимы только к операндам типа int. Результат операции имеет тип int. Второй аргумент операции (количество бит сдвига) должен находиться в отрезке от 0 до 32 включительно. Если это условие не выполняется, генерируется ошибка недопустимого аргумента операции. Сдвиг вправо выполняется как побитовый сдвиг, то есть на место старших разрядов числа помещаются нулевые биты. Переполнения при сдвиге влево не диагностируется.

Операции отношения == и !=

Операции проверки на равенство или неравенство применимы ко всем типам данных. Оба аргумента должны иметь один и тот же тип. Неявных преобразований типа не производится. Результат операции имеет тип bool.

Операции отношения <, >, <=, >=

Данные операции применимы ко всем типам данных, кроме result_t, hash_t и ip_t. Оба аргумента операции должны иметь один и тот же тип данных. Результат операции имеет тип bool.

Сопоставление с регулярным выражением ~=

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

Побитовые операции ^, &, |

Побитовые операции применимы только к аргументам типа int и в результате дают значение типа int.

Логические операции && и ||

Логические операции применимы только к аргументам типа bool и дают в результате значение типа bool. Как и в языке Си значение второго аргумента операции не вычисляется, если значение всего выражение известно.

Примеры