2013-05-16 4 views
6

Wie findet man ein beliebiges Symbol im ANTLR-Parser (nicht Lexer)? Wo ist die vollständige Sprachbeschreibung für ANTLR4-Parser?Wie findet man ein beliebiges Symbol im ANTLR-Parser (nicht Lexer)?

UPDATE

Ist die Antwort "unmöglich"?

+0

Die Antwort auf Ihre aktualisierte Frage lautet: Ja, es ist unmöglich (wie ich in meiner Antwort angegeben habe). –

+0

Ich habe keine Ahnung was genau du brauchst. Aber vielleicht sollten Sie sich "Inselgrammatiken" anschauen. Es sollte in Fällen hilfreich sein, in denen Sie eine Eingabe mit zwei verschiedenen Grammatiken analysieren müssen. – ibre5041

Antwort

4

Es hängt davon ab, was Sie mit "Symbol" meinen. Verwenden Sie das Metazeichen . (DOT), um mit einem Token in einer Parserregel übereinzustimmen. Wenn Sie versuchen, ein beliebiges Zeichen innerhalb einer Parser-Regel abzugleichen, dann haben Sie Pech gehabt. In ANTLR gibt es eine strikte Trennung zwischen Parser- und Lexer-Regeln. Es ist nicht möglich, ein beliebiges Zeichen innerhalb einer Parser-Regel abzugleichen.

+0

Schränkt dies nicht ernsthaft die Arbeit mit Unicode ein?Unicode besteht aus Tausenden von Symbolen und ANTLR erlaubt mir, entweder die meisten davon als dasselbe Token zu behandeln oder eine Lexer-Definition für jedes zu erstellen. Sieht nach ernsthaft schlechtem Design aus. Ist es nicht? –

+0

P.S. Angenommen, ich möchte Java String Literal beschreiben. Es ist in Anführungszeichen eingeschlossen, kann aber alles enthalten. Wenn ich es mit Lexer analysiere, werde ich seinen Inhalt verlieren. Warum so anders beim Integer-Literal? –

+0

@SuzanCioc sorry, ich habe keine Ahnung was du meinst. String-Literale werden normalerweise im Lexer behandelt. Warum sollten Sie sie in einer Parser-Regel behandeln? –

5

Als erstes müssen Sie die Rollen der einzelnen Teile in Parsing verstehen:

Der Lexer: das ist das Objekt, das Ihr Eingabestring tokenizes. Token bedeutet, einen Strom von eingegebenen Zeichen in ein abstraktes Tokensymbol (normalerweise nur eine Zahl) umzuwandeln.

Der Parser: Dies ist das Objekt, das nur mit Token funktioniert, um die Struktur einer Sprache zu bestimmen. Eine Sprache (als eine oder mehrere Grammatikdateien geschrieben) definiert die Tokenkombinationen, die gültig sind.

Wie Sie sehen können, weiß der Parser nicht einmal, was ein Buchstabe ist. Es kennt nur Token. Deine Frage ist also schon falsch. Es ist, als würde man fragen, wie man mit einer Kettensäge einzelne Atome herausschneidet.

Ich sagte, dass es wahrscheinlich helfen würde zu wissen, warum Sie einzelne Eingabebuchstaben in Ihrem Parser überspringen möchten. Es sieht so aus, als ob Ihr Basiskonzept Anpassungen erfordert.

+0

Wie vorheriger Beantworter sagte, gibt es in ANTLR DOT-Meta-Zeichen. Es hätte auch eine Lexer-Metaregel, um alle Zeichen in 1: 1-Weise in Token umzuwandeln. Ich sehe keinen Grund, Lexer überhaupt zu haben. Es wird Tagging als Parser, aber schlechte und begrenzte Tagging. Es ist redundantes Konstrukt. –

+0

@SuzanCioc, Sie verwenden nur das falsche Werkzeug. ANTLR funktioniert nicht so, wie Sie es erwarten/wollen. Was Sie wollen, ist eine PEG, keine Notwendigkeit, sich darüber zu beschweren, dass ANTLR nicht so tut, wie Sie es erwarten. –

+0

PEG ist ein Werkzeug oder eine Idee? –

2

Es ist möglich, aber nur wenn Sie solch eine grundlegende Grammatik haben, wird der Grund, ANTlr zu verwenden, sowieso negiert.

Wenn Sie die Grammatik hatte:

text  : ANY_CHAR* ; 
ANY_CHAR : . ; 

es tun würde, was Sie (scheinbar) wollen.

Wie jedoch viele darauf hingewiesen haben, wäre dies eine ziemlich seltsame Sache zu tun. Der Zweck des Lexers ist es, verschiedene Tokens zu identifizieren, die im Parser zu einer Grammatik zusammengefügt werden können, so dass Ihr Lexer entweder die spezifische Zeichenfolge "JSTL/EL" als Token oder [AZ] '/ EL' identifizieren kann. , [AZ] '/' [AZ] [AZ], usw. - je nachdem, was Sie brauchen.

Der Parser wird dann verwendet, um die Grammatik zu definieren, so:

phrase  : CHAR* jstl CHAR* ; 
jstl  : JSTL SLASH QUALIFIER ; 

JSTL  : 'JSTL' ; 
SLASH  : '/' 
QUALIFIER : [A-Z][A-Z] ; 
CHAR  : . ; 

würde "Blabla JSTL/EL ..." als Eingabe akzeptieren, aber nicht "Blabla EL/JSTL ..." .

Ich würde empfehlen, die Definitive ANTlr 4 Reference, insbesondere den Abschnitt "Inseln im Stream" und die Grammatik-Referenz (Ch 15), die sich speziell mit Unicode befasst.

+0

Ihre 'Phrasen'-Regel funktioniert nicht mit der Phrase" JSTL ist eine großgeschriebene Version von jstl ", weil Lexer zuerst" JSTL "als' JSTL' Token isst und es dann nicht mit der Phrasenregel übereinstimmt. Also, die Idee von Lexer ist nur eine schlechte Idee. –

+0

Das ist ziemlich bizarr, als ich mit ANTlr anfing, hatte ich ziemlich genau die gegenteilige Ansicht - und kam mir einige Male sehr nahe, nur den Lexer zu benutzen, um Token zu erstellen und dann meinen eigenen Parser außerhalb von ANTlr zu schreiben. Alles, was ich sagen kann ist, dass, für viele der einfachen Grammatiken hier, die Leute verwenden, um Bugs und/oder Missverständnisse zu diskutieren, ja, es scheint wie ein Overkill, sowohl einen Parser als auch einen Lexer zu haben. Sobald die Dinge jedoch kompliziert werden, ist die Aufteilung vorteilhaft - sowohl die Lexer- als auch die Parsergrammatik für unsere Anwendung laufen hier auf 100 Zeilen, und wir finden diese Entkopplung als eine gute Idee. – Dave

Verwandte Themen