Wenn Sie eine ("theoretische") Grammatik mit einer Regel mit einer leeren rechten Seite schreiben, verwenden Sie immer ein Symbol wie ε (oder 1), um diese Leerstelle explizit zu machen :Eine Notation für leere rechte Seiten der Regeln
A → ε | a A
eine solche Grammatik in Yacc und andere aussehen würde dann wie
a: | 'a' a
oder "schlechter"
a: { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
Die Tatsache, dass in "Realwelt-Grammatiken" (Yacc, Bison usw.) dieser leere rechte Teil der Regel nicht explizit als leer markiert ist, beunruhigt mich: Es ist leicht zu übersehen, dass ein rhs leer ist, oder schlimmer : vergessen |
einzusetzen und verwenden tatsächlich eine Aktion Mitte der Regel:
a: { $$ = new_list(); }
a 'a' { $$ = $1; $$->append($1); }
;
1) ich von Werkzeug nicht wissen, dass sie zu einem leeren rhs explizit machen bietet. Sind da irgendwelche?
Zukünftige Versionen von Bison unterstützen möglicherweise ein dediziertes Symbol mit Fehlern, wenn es in einer nicht leeren rhs verwendet wird, und Warnungen, wenn eine implizit leere rhs übrig ist.
2) Halten die Leute das für nützlich?
3) Welche Schreibweise würden Sie vorschlagen?
Derzeit ist der Kandidat $empty
:
a: $empty { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
EDIT
Die gewählte Syntax ist %empty
:
a: %empty { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
Tat $empty
sieht aus wie ein pseudo-Symbol, wie $accept
dass Bison generiert für die erste Regel oder die [email protected]
Pseudosymbole für Mid-Regel-Aktionen oder $eof
für, nun, Ende der Datei. Aber es ist definitiv kein Symbol, es ist gerade die Abwesenheit von Symbolen.
Auf der anderen Seite bezeichnet %
eindeutig eine Direktive (irgendeine Art von Attribut/Metadaten), wie %pred
.
Es ist also ein kleiner Unterschied der Syntax, aber es ist mehr konsistent mit der Gesamtsyntax. Der Dank geht an Joel E. Denny.
Danke. Wir werden wahrscheinlich '% empty' stattdessen verwenden (als ein Pseudosymbol, nicht als eine Direktive, wie von Chris in seiner Antwort vorgeschlagen), da es wirklich ein Schlüsselwort ist, kein Symbol (es ist kein Terminal, wie' $ end ', noch ein Nichtterminal, wie' $ accept'). – akim