2017-05-27 3 views
2

Ich habe die folgende Grammatik:Warum ist das parsable

grammar Demo; 

program: command 
     IDENTIFIER 
     ; 

command: 
     | 'add' 
     | 'remove' 
     ; 

IDENTIFIER: [a-zA-Z][a-zA-Z0-9]* ; 

WHITESPACE: [ \t\n\r]+ -> skip; 

Jetzt kann ich eingegeben so etwas wie „add foo“ und ich bekomme das richtige Ergebnis. Aber er akzeptiert auch nur "foo". Ich dachte, dass der Parser eine Ausnahme auslösen wird, weil der Wert mit einem der Befehle beginnen muss? Gibt es eine Option, um das Problem zu beheben? Oder habe ich einen Fehlschluss?

+5

Ich weiß nicht, ANTLR, aber ich nehme an, die ersten '|' Zeichen das Problem zu sein, so dass eine leere Eingabe ermöglicht. Vielleicht ändere es zu 'command: 'add' | 'entfernen'; '? – Seelenvirtuose

Antwort

3

Wie in den Kommentaren von Seelenvirtuose angezeigt, das Problem ist, dass die Regel für command einen leeren Befehl ermöglicht es, sollte es sein:

command: 
     'add' 
     | 'remove' 
     ; 

Das Pipe-Symbol (|) ein Trennzeichen zwischen Alternativen ist, in Ihrem Originalcode es trennte eine leere Produktion von 'add'.

jedoch wie es ist, würde die Grammatik nur foo immer noch erlauben, Match, das, weil Sie keine expliziten EOF-Token in Ihrer program Regel (ähnlich die $ Option in einem regulären Ausdruck) haben Sie ist. Ohne das EOF-Token stimmt der Parser glücklich überein und ignoriert den Rest. Also, wenn das nicht das gewünschte Verhalten immer Ihre Hauptregel mit EOF Ende:

program: command IDENTIFIER EOF; 
+0

@MikeLischke Ich habe das Antwort-Community-Wiki erstellt, füge es gerne der Antwort hinzu :) –

+0

Fertig, keine Notwendigkeit, dieses Community-Wiki zu erstellen, allerdings :-) –