Eu estou forçado a usar% glr-parser?
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.
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.