Pergunta

Estou tentando projetar uma gramática de ilha usando Malandro MPL, mas me deparei com um problema:

Ao implementar uma Gramática de Ilha no SDF, uma abordagem muito comum é definir uma produção de água "pega-tudo" usando o atributo {evitar}.Isto evita que o analisador utilize esta produção se outras forem aplicáveis.Isto permite especificar um comportamento padrão que pode ser superada por outras produções sem gerar ambiguidades.Um exemplo muito simples disso seria:

context free syntax
    Chunk*         -> Input
    Water          -> Chunk
lexical syntax
    ~[\t\n\ ]+   -> Water {avoid}  // avoid the Water production

Tentei reproduzir esse comportamento com Rascal MPL.Meu objetivo é criar uma gramática de ilha que reúna todas as diretivas condicionais do pré-processador dentro de um trecho de código C/C++ e ignore o restante da entrada usando produções Water.

layout LAYOUT = [\t\n\ ];
lexical WATER = ![\t\n\ ]+;

start syntax Program = Line*;       // program consists of lines

syntax Line = ConditionalDirective  // preprocessor directives
            > WATER;                // catch-all option

syntax ConditionalDirective = "#ifdef" 
                            | "#ifndef"
                            | "#if"
                            | "#elif";

Tentei criar o efeito {evitar} dando o Diretriz Condicional produção com prioridade mais alta usando o operador ">", mas aparentemente isso não funciona.A árvore de análise ainda contém ambigüidades.

#ifdef asd

Se eu analisar o código acima, por exemplo, obtenho uma árvore de análise semelhante a esta:

ambiguous parse tree

Pelo que posso dizer do Documentação Rascal, usar o operador "prioridade" pode não ser o caminho a seguir no meu caso, mas não vejo outras possibilidades.Presumo que haja uma maneira, porque os autores de rascal afirmam claramente que toda gramática SDF pode ser convertida em uma gramática malandra.

Existe uma maneira de reproduzir a funcionalidade {evitar} dos SDFs com MPL malandro?Ou é possível filtrar de alguma forma a floresta de análise, reaplicando as prioridades?

Foi útil?

Solução

Resposta curta:evite está no sdf2 um filtro pós-análise.No rascal você mesmo pode definir isso, veja https://github.com/cwi-swat/rascal/blob/master/src/org/rascalmpl/library/lang/sdf2/filters/PreferAvoid.rsc para um exemplo que imita o comportamento de evitar sdf2 sem ignorar as cadeias de injeção e sem contar.Você pode importá-lo em sua gramática e usar as tags @avoid e @prefer como no sdf2, ou escrever seus próprios filtros.

Embargo:evitar geralmente não foi suficiente para definir o comportamento da água no sdf2 e também não é no rascal.A razão é que a água pode demorar mais do que sua alternativa.Preferir e evitar só pode escolher entre alternativas de igual comprimento em termos de comprimento de subsentença.Uma maneira infalível, mas lenta, de lidar com a água no malandro é contá-la em todas as alternativas e escolher derivações com menos água.

Outro problema com preferir e evitar era que os usos começavam a interferir, principalmente quando eram contados.Isso pode ser evitado no Rascal especializando filtros para não-terminais específicos ou até mesmo para regras alternativas.

Outra opção é usar \ e !operadores de desambigação.Consulte o manual.No entanto, toda e tudo o que acredito que a opção de filtragem de parse post é atualmente a melhor maneira de lidar com as gramáticas da ilha porque você controla o que está acontecendo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top