Domanda

Ho sintassi del tipo

%(var)

e

%var

e     (Var)

Le mie regole sono qualcosa come

optExpr:
    | '%''('CommaLoop')'
    | '%' CommaLoop

CommaLoop:
    val | CommaLoop',' val

Expr:
    MoreRules
    | '(' val ')'

Il problema è che pretende molto sembra essere in grado di dire se) appartiene alla %(CommaLoop) o % (val) ma lamenta il) al posto della (. Che diamine? Shouldnt si lamentano su (? E come devo correggere l'errore? Credo che facendo %( un token è una buona soluzione, ma voglio essere sicuro perché $( è neanche un errore prima di fare questo.

È stato utile?

Soluzione

Ciò è dovuto al modo in cui le opere LR parsing. LR analisi è effettivamente basso verso l'alto, raggruppando gettoni in base al RHS delle regole grammaticali, e la loro sostituzione con l'LHS. Quando il parser 'sposta', mette un gettone sullo stack, ma in realtà non corrisponde a una regola ancora. Invece, che riproduce parzialmente regole abbinato con lo stato attuale. Quando si arriva ad uno stato che corrisponde alla fine della regola, può ridurre, spuntando i simboli per la RHS dallo stack e spingendo indietro un unico simbolo che denota l'LHS. Quindi, se ci sono conflitti, non mostrano fino a quando il parser arriva alla fine di qualche regola e non può decidere se ridurre (o quello che per ridurre).

Nel tuo esempio, dopo aver visto % ( val , che è ciò che sarà sullo stack ( superiore è sul lato destro qui) Quando il lookahead è ) , non può decidere se dovrebbe pop val e ridurre tramite la regola CommaLoop:. val , o se dovesse spostare la ) in modo che possa poi pop 3 cose e ridurre con la regola Expr: '(' val ')'

Sto assumendo qui che si dispone di alcune regole aggiuntive come CommaLoop:. Expr , altrimenti la tua grammatica non corrisponde in realtà nulla e bisonte / yacc si lamentano non-terminali inutilizzati

Altri suggerimenti

In questo momento, la tua spiegazione e la tua grammatica non sembrano corrispondere. Nella tua spiegazione, si mostrano tutte e tre le frasi come avere 'var', ma la grammatica mostra quelli che iniziano con '%' a permettere ad un elenco separato da virgole, mentre quello senza consente solo un singolo 'val'.

Per il momento, darò per scontato tutti e tre dovrebbero consentire a un elenco separato da virgole. In questo caso, mi piacerebbe fattore la grammatica più simile a questo:

optExpr: '%' aList

aList: CommaLoop
    | parenList

parenList: '(' CommaLoop ')'

CommaLoop: 
    | val 
    | CommaLoop ',' val

Expr: MoreRules
    | parenList

Ho cambiato optExpr e Espr così nessuno dei due può abbinare una sequenza vuota - la mia ipotesi è che probabilmente non intendeva che per cominciare. Ho polpa questo fuori sufficiente per eseguire attraverso byacc; produce nessun avviso o errori.

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