Uma frase de permutação é uma extensão das definições gramaticais livres de contexto (E) BNF: uma frase de permutação contém produções (ou equivalentes, não terminais) a . Na posição da frase de permutação, gostaríamos de ver cada uma dessas produções exatamente uma vez, mas não estamos interessados em ordenar essas não-terminais.
Por exemplo:
S <- X { A, B, C } Y
é equivalente a:
S <- X A B C Y
S <- X A C B Y
S <- X B A C Y
S <- X B C A Y
S <- X C A B Y
S <- X C B A Y
O conceito parece ser introduzido em "Estendendo gramáticas sem contexto com frases de permutação" . Nele também é descrito como analisar essas frases em tempo linear usando um analisador LL (1).
O documento "Analisando frases de permutação" descreve um método para analisar frases de permutação usando combinadores de analisador. Estes são os únicos dois artigos que encontrei que falam sobre frases de permutação e como analisá-las.
Visto que podemos analisar facilmente esses tipos de frases de permutação com analisadores baseados em LL (1), meu palpite seria que podemos fazer o mesmo com analisadores de estilo LR (1). Minha pergunta é, portanto:
Uma gramática contendo frases de permutação pode ser analisada no tempo linear no tamanho da string de entrada usando máquinas LR (1) enquanto mantém uma tabela de tamanho razoável?
Embora isso seja melhor, é claro que não é bom o suficiente - ter uma frase de permutação de 30 itens tornaria a gramática inutilizável. Ainda existe uma parte da análise de LR que ainda não tocamos, e esse é o procedimento baseado em pilha real usado para a análise. Imagino que armazenar contadores na pilha possa resolver o problema, mas não sei como fazer isso.
No momento, estou implementando um gerador de analisador e, no domínio do problema, as frases de permutação seriam um presente do céu. Como estou usando máquinas LR (1), a pergunta acima se seguiu.
fonte
Respostas:
Você já pensou em converter isso em um problema semântico? Em vez de regras gramaticais para todas as permutações de não-terminais {A, B, C}, basta ter uma regra para reconhecer (A | B | C) ^ 3 junto com o código interno especial que garante que apenas um de cada seja reconhecido, caso contrário, declara um erro. Eu inseriria uma produção vazia antes da cláusula acima, cuja redução aciona a inicialização do que você está usando para contar A, B e C e uma depois, cuja redução aciona a verificação do contador e (se necessário) afirma o erro. (é claro que isso pode ser um pouco complicado se a gramática for recursiva em A, B e / ou C)
fonte
Eu não acho que alguém precise de um balcão. Basicamente, você apenas verifica todas as permutações, mas quebra
pseudo-código:
Aqui está um exemplo mais concreto
Suponha que estamos tentando corresponder a qualquer permutação de abcd e nossa string é bcda
Então você vê que esse algoritmo simples pode verificar uma permutação facilmente, simplesmente comparando "strings" fora de ordem. Observe que a complexidade da função é O (n!) Pior caso e O (1) melhor caso. Em certo sentido, estamos mantendo a contagem armazenando os símbolos para combinar em uma matriz. Eu pensaria que isso seria "rápido" em geral, uma vez que não se lida com n muito grande na maioria dos casos.
fonte