В этой задаче вы должны написать программу, которая читает регулярное выражение и генерирует другую программу, которая выводит, принята ли входная строка этим регулярным выражением. Вывод должен быть программой, написанной на том же языке, что и ваша заявка.
вход
Ввода является регулярным выражением г соответствия следующей ABNF (начальное правило производства REGEX
):
REGEX = *( STAR / GROUP / LITERAL / ALTERNATIVE )
STAR = REGEX '*'
GROUP = '(' REGEX ')'
LITERAL = ALPHA / DIGIT
ALTERNATIVE = REGEX '|' REGEX
Если ввод не соответствует этой грамматике, поведение вашей программы не определено.
интерпретация
Интерпретировать входные данные как регулярное выражение, где *
Kleene-star (имеется в виду повторение левого аргумента ноль или более раз ), |
является альтернативой, (
а )
группа и ни один оператор вообще не объединены. Группировка имеет приоритет над звездой, звезда имеет приоритет над конкатенацией, конкатенация имеет приоритет над альтернативой.
Строка считается принятой, если регулярное выражение соответствует всей строке.
Выход
Вывод программы - это другая программа, написанная на том же языке, что и ваша заявка, которая читает строку s определенным для реализации способом во время выполнения, выводит, принимает ли r s, а затем завершает работу. Вывод может быть сделан пользовательским способом, хотя для принятых и отклоненных программ должно быть только два отдельных вывода.
Вы можете предположить, что ввод вашей выходной программы никогда не будет длиннее 2 16 -1 байт.
ограничения
Ни ваша заявка, ни какая-либо программа, созданная вами, не могут использовать встроенные функции или библиотеки, которые
- соответствие регулярных выражений
- преобразовать регулярные выражения
- компилировать регулярные выражения
- генерировать парсеры из грамматики
- упростить задачу таким образом, чтобы ваше представление стало тривиальным
счет
Оценка вашего представления - это количество символов. Представление с самым низким счетом выигрывает.
Testcases
Все тестовые случаи содержат регулярное выражение, набор принятых строк, набор отклоненных строк и пример программы на C99, которая является действительным выводом (гипотетической) отправки C99.
(пустое регулярное выражение)
Принимаемые строки
- (пустой ввод)
Отклоненные строки
- Foo
- бар
- Baz
- quux
Пример программы
#include <stdio.h>
int main() {
char input[65536];
gets(input);
return input[0] != 0;
}
(b|)(ab)*(a|)
( a
и b
чередующийся)
принятые строки
a
ba
abababababa
abab
отклоненные строки
afba
foo
babba
пример программы
#include <stdio.h>
int main() {
char input[65536];
int state = 0;
for (;;) switch (state) {
case 0: switch (getchar()) {
case 'a': state = 1; break;
case 'b': state = 2; break;
case EOF: return 0;
default: return 1;
} break;
case 1: switch (getchar()) {
case 'b': state = 2; break;
case EOF: return 0;
default: return 1;
} break;
case 2: switch (getchar()) {
case 'a': state = 1; break;
case EOF: return 0;
default: return 1;
} break;
}
(0|1(0|1)*)(|A(0|1)*1)
(двоичные числа с плавающей точкой)
принятые строки
- 10110100
- 0
- 1A00001
отклоненные строки
- 011
- 10А
- 1A00
- 100A010
return (regex.match(stdin) is not null)
запрещено.Ответы:
Рубин,
641651543 символовЭта версия ruby стала довольно длинной из-за нескольких угловых случаев в синтаксическом анализаторе регулярных выражений (возможно, я должен попробовать другой подход). Он ожидает регулярное выражение в STDIN и выводит соответствующий код ruby для сопоставителя в STDOUT.
Программа непосредственно генерирует код для NFA-ε, который затем выполняется в средстве сопоставления.
Тестовый пример 1: (вывод включает в себя дополнительные переводы строки и отступы)
Контрольный пример 2:
Другой пример:
Редактировать: Добавлен переход для исправления ошибки, пожалуйста, отметьте в комментариях. Также изменилась инициализация состояния.
источник
011
для регулярного выражения(0|1(0|1)*)(|A(0|1)*1)
приводит кtrue
- это должно бытьfalse
.C 627 знаков
Эта программа обрабатывает свой первый аргумент командной строки как входные данные и генерирует C-код как свои выходные данные.
Вот его вывод для
(0|1(0|1)*)(|A(0|1)*1)
(с добавленными символами новой строки):Если вы в качестве первого аргумента командной строки предоставите действительный ввод, он вернет статус выхода 1. В противном случае он вернет статус выхода 0.
Любая из программ, если вы не предоставите аргумент командной строки, разыменовывает нулевой указатель, вызывая ошибку сегментации. Достаточно длинное регулярное выражение переполнит буферы этого представления, а размер ввода в сгенерированную программу ограничен размером стека. Тем не менее, все тесты работают.
Обратите внимание, что
e(g=h++,C=h++,0,0);
вводит неопределенное поведение. Если, например, сгенерированные программы не компилируются, вы можете попробовать заменить оператор наh+=2;e(g=h-1,C=h-2,0,0);
пять символов длиннее.источник