Pergunta

Tenho mantido a mudança / reduzir os erros de distância. Agora, finalmente, eu acho que eu conheci o meu jogo.

Int[] a
a[0] = 1

O problema é int [] é definido como

Type OptSquareBrackets

enquanto a [0] é definida como

Var | Var '[' expr ']'

Var e Tipo ambos são definidos como VAR que é qualquer [a-zA-Z][a-zA-Z0-9_] variável válido. Além de adicionar um símbolo fictício (como **Decl** Type OptSquareBrackets vez) há uma maneira de escrever isso para não ter um conflito? Deste uma regra i get 1 shift / reduzir e 1 reduzir / reduzir aviso.

Foi útil?

Solução

Você poderia definir um novo token

VarLBracket [a-zA-Z][a-zA-Z0-9_]*\[

E, portanto, definir declaração

Type | VarLBracket ']';

e definir destino da atribuição como

Var | VarLBracket expr ']';

Outras dicas

Crie uma regra de Lex com [] desde [] só é usado em declaração e qualquer outro lugar usaria [var]

Tecnicamente, este problema decorre tentando amarrar a gramática a um significado semântico que realmente não diferem em sintaxe.

ISTM que você só precisa de uma única construção gramática que descreve os dois tipos e expressões. Fazer a distinção em código e não na gramática, especialmente se não há realmente uma diferença sintática. Yacc é chamado um gerador de compilador, mas não é nem um pouco verdade. Ela só faz analisadores.

Dito isto, reconhecendo [] como um símbolo de terminal pode ser uma maneira mais fácil de resolver o problema e continuar com as coisas. Yacc não é muito bom em gramática ambígua e ele precisa para tomar decisões antecipadas em qual caminho seguir.

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