analisador BNF gramática + Ouro LALR, não distinguir NewLine caso especial de Whitespace

StackOverflow https://stackoverflow.com/questions/599409

  •  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}
Foi útil?

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.

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