Nesta tarefa, você deve escrever um programa que leia uma expressão regular e gere outro programa que mostre se uma sequência de entrada é aceita por essa expressão regular. A saída deve ser um programa escrito no mesmo idioma que seu envio.
Entrada
A entrada é uma expressão regular r que corresponde ao seguinte ABNF (a regra de produção inicial é REGEX
):
REGEX = *( STAR / GROUP / LITERAL / ALTERNATIVE )
STAR = REGEX '*'
GROUP = '(' REGEX ')'
LITERAL = ALPHA / DIGIT
ALTERNATIVE = REGEX '|' REGEX
Se a entrada não corresponder a esta gramática, o comportamento do seu programa é indefinido.
Interpretação
Interprete a entrada como uma expressão regular, onde *
está a estrela Kleene (significando repetir o argumento esquerdo zero ou mais vezes ), |
é uma alternativa, (
e o )
grupo e nenhum operador são concatenados. O agrupamento tem precedência sobre a estrela, a estrela tem precedência sobre a concatenação, a concatenação tem precedência sobre a alternativa.
Diz-se que uma string é aceita se o regex corresponder à string inteira.
Resultado
A saída do programa é outro programa escrito na mesma língua que a sua apresentação que lê uma cadeia s de uma forma implementação definida em tempo de execução, as saídas se r aceita s e depois termina. A saída pode ser feita de maneira definida pelo usuário, embora deva haver apenas duas saídas distintas para programas aceitos e rejeitados.
Você pode supor que a entrada do seu programa de saída nunca seja maior que 2 16 -1 bytes.
Restrições
Nem seu envio nem qualquer programa gerado por ele pode usar a funcionalidade interna ou bibliotecas que
- regexes de correspondência
- transformar expressões regulares
- compilar expressões regulares
- gerar analisadores a partir de uma gramática
- simplifique o problema de maneira que sua submissão se torne trivial
Pontuação
A pontuação do seu envio é o número de caracteres. A finalização com a menor pontuação vence.
Casos de teste
Todos os casos de teste contêm uma expressão regular, um conjunto de cadeias aceitas, um conjunto de cadeias rejeitadas e um programa de exemplo no C99, que é uma saída válida de um envio (hipotético) de C99.
(expressão regular vazia)
Strings aceitas
- (entrada vazia)
Cadeias rejeitadas
- foo
- Barra
- baz
- quux
Programa de exemplo
#include <stdio.h>
int main() {
char input[65536];
gets(input);
return input[0] != 0;
}
(b|)(ab)*(a|)
( a
e b
alternando)
cordas aceitas
a
ba
abababababa
abab
cadeias rejeitadas
afba
foo
babba
programa de exemplo
#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)
(números binários de ponto flutuante)
cordas aceitas
- 10110100
- 0 0
- 1A00001
cadeias rejeitadas
- 011
- 10A
- 1A00
- 100A010
return (regex.match(stdin) is not null)
não seja permitido.Respostas:
Ruby,
641651543 caracteresEssa versão do ruby se tornou bastante longa devido a vários casos de canto no analisador de expressões regulares (talvez eu devesse tentar uma abordagem diferente). Ele espera a expressão regular em STDIN e gera o código ruby correspondente para o correspondente em STDOUT.
O programa gera código diretamente para um NFA-ε que é então executado no matcher.
Caso de teste 1: (a saída inclui novas linhas e recuo adicionais)
Caso de teste 2:
Outro exemplo:
Edit: Adicionada uma transição para corrigir o bug PleaseStand anotado nos comentários. Também mudou a inicialização do estado.
fonte
011
para(0|1(0|1)*)(|A(0|1)*1)
resultados de regextrue
- deve serfalse
.C, 627 caracteres
Este programa trata seu primeiro argumento de linha de comando como entrada e gera código C como saída.
Aqui está sua saída para
(0|1(0|1)*)(|A(0|1)*1)
(com novas linhas adicionadas):Se você fornecer entrada válida como seu primeiro argumento de linha de comando, ele retornará o status de saída 1. Caso contrário, ele retornará o status de saída 0.
Qualquer um dos programas, se você não fornecer o argumento da linha de comandos, desreferencia um ponteiro nulo, causando uma falha de segmentação. Uma regex suficientemente longa excederá os buffers desse envio e o tamanho da entrada para um programa gerado é limitado pelo tamanho da pilha. No entanto, todos os casos de teste funcionam.
Observe que
e(g=h++,C=h++,0,0);
apresenta um comportamento indefinido. Se, por exemplo, os programas gerados não forem compilados, você poderá tentar substituir a instrução porh+=2;e(g=h-1,C=h-2,0,0);
cinco caracteres a mais.fonte