analisador BNF gramática + Ouro LALR, não distinguir NewLine caso especial de Whitespace
-
11-09-2019 - |
Pergunta
- I considerar espaços em branco e quebras de linha como espaços em branco normais.
- Quero distinguir novas linhas de outros espaços em branco, além disso, para permitir caso especial.
Primeira tentativa de escrever uma gramática compatível falhar.
Aqui é a gramática:
! ------------------------------------------------- Sets
{WS} = {Whitespace} - {CR} - {LF}
{ID Head} = {Letter} + [_]
{ID Tail} = {Alphanumeric} + [_]
{String Chars} = {Printable} + {HT} - ["\]
! ------------------------------------------------- Terminals
! The following defines the Whitespace terminal using the {WS}
! set - which excludes the carriage return and line feed
! characters
Whitespace = {WS}+ | {CR}{LF} | {CR} | {LF}
!NewLine = {CR}{LF} | {CR} | {LF}
MyNewLine = {CR}{LF} | {CR} | {LF}
Solução
Eles são ambíguos porque ambos contêm o mesmo sub-conjunto {CR}{LF} | {CR} | {LF}
.
Dada a {CR}{LF}
entrada do analisador não tem nenhuma maneira de saber qual terminal deve corresponder.
Um analisador baseado em tabela não é realmente concebido para lidar com "casos especiais" diretamente. Se você deseja ignorar novas linhas em alguns contextos, mas significado atribuir-lhes em outros, então você vai ter que lidar com isso em suas reduções (ou seja tokenizar as novas linhas separadamente, e descartá-los em suas reduções), mas isso vai ficar feia .
A (potencialmente) melhor solução é usar tokenizer estados (possivelmente controlados a partir do analisador), para mudar a forma como as entradas de nova linha são indexado. É difícil dizer sem entender sua gramática. Além disso, tem sido alguns anos desde que eu tenha mexido com este material.
Outras dicas
Eu acho que a gramática é ambígua no sentido de que tanto espaço em branco e MyNewLine corresponder novos charachters linha. Uma vez que lança uma vacilante fazê-lo seu caminho, eu sugiro a detecção de espaço em branco e novas linhas separadamente e decidir o que fazer com a nova linha em uma base caso a caso.
Eu não sou muito experiente na área, mas isso é o que eu me lembro da minha teoria da classe Computação e Compiler Classe de Design.
Espero que isso ajude.
A resposta final.
Para meu espanto, eu sou apenas uma recente início tardio ;-) membro.
Mantenha usando o habitual Line-Based Grammar declarações
! ====================================================================
{Whitespace Ch} = {Whitespace} - {CR} - {LF}
Whitespace = {Whitespace Ch}+
Newline = {CR}{LF} | {CR} | {LF}
! ====================================================================
Whitespace vs. nova linha distinção já é levado em conta!
Considere o endereçamento do caso especial ao escrever suas regras de produção.
Para o caso complexo que você pode até mesmo necessidade de definir alguns terminal virtual (técnica avançada).
Você pode elaborar a sua gramática e perguntar por publicá-la novamente.
Última Editar : Por favor, compartilhe se você já abordou a questão. Obrigado.