Domanda

Ho tenuto lontano lo spostamento / riduzione degli errori. Ora finalmente penso di aver incontrato la mia partita.

Int[] a
a[0] = 1

Il problema è int [] è definito come

Type OptSquareBrackets

mentre uno [0] è definito come

Var | Var '[' expr ']'

Var e Type sono entrambi definiti come VAR che è una variabile valida [a-zA-Z] [a-zA-Z0-9_] . Oltre ad aggiungere un token fittizio (come ** Decl ** Type OptSquareBrackets ) c'è un modo per scrivere questo per non avere un conflitto? Da questa regola ottengo 1 spostamento / riduzione e 1 avviso di riduzione / riduzione.

È stato utile?

Soluzione

Potresti definire un nuovo token

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

E quindi definire la dichiarazione

Type | VarLBracket ']';

e definire il target di assegnazione come

Var | VarLBracket expr ']';

Altri suggerimenti

Crea una regola Lex con [] poiché [] viene utilizzato solo nella dichiarazione e in qualsiasi altro luogo verrebbe utilizzato [var]

Tecnicamente, questo problema deriva dal tentativo di legare la grammatica a un significato semantico che in realtà non differisce nella sintassi.

ISTM che ti serve solo un singolo costrutto grammaticale che descriva sia i tipi che le espressioni. Fai la distinzione nel codice e non nella grammatica, specialmente se in realtà non c'è una differenza sintattica. Yacc è chiamato un generatore di compilatore ma non è affatto vero. Produce solo parser.

Detto questo, riconoscere [] come simbolo terminale potrebbe essere un modo più semplice per risolvere il problema e andare avanti con le cose. Yacc non è molto bravo nelle grammatiche ambigue e deve prendere le prime decisioni su quale percorso seguire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top