Forum: PC-Programmierung C# & ANTLR - Parserregeln aus Lexerregeln


von Farin (Gast)


Lesenswert?

Hei zusammen

Ich habe eine Frage zu dieser ANTLR-Grammatik. Ich habe jetzt alles als 
Lexer-Regeln eingebaut was aber offensichtlich nicht stimmen kann. Wie 
muss ich den Code umstellen dass er mir einen Parserbaum ausgibt. Ich 
hoffe ihr könnt mir helfen. :)

Vielen Dank & Gruss

Farin
1
grammar test;  
2
options
3
{
4
  language=CSharp2;
5
  backtrack=true;
6
}
7
Call            : Statement';';
8
Statement       : FunctionName '(' ArrowConstruct (',' ArrowConstruct)* ')';
9
FunctionName    : (Object '.CALL' | Object '.ADD');
10
ArrowConstruct  : String '=>' Argument;
11
Object          : Identifier;
12
Identifier      : Alpha AlphaNum*;
13
Argument        : (String | Number | Statement | Boolean);
14
String          : '"' AlphaNum+ '"';
15
Boolean         : 'TRUE'|'FALSE';
16
Alpha           : 'a'..'z' | 'A'..'Z';
17
Digit           : '0'..'9';
18
AlphaNum        : Alpha | Digit;
19
Number          : Digit+;
20
NumComparison   : ('<'|'>'|'=='|'!='|'<='|'>=');
21
BoolComparison  : ('=='|'!=');
22
Value           : (Number | Statement);
23
BoolCondition   : '('Boolean BoolComparison Boolean')';
24
NumCondition    : '('Value NumComparison Value')';
25
Condition       : (BoolCondition|NumCondition);
26
While           : 'WHILE' Condition '{' Call+ '}';
27
CodeBlock       : (While | Call)+;

von Farin (Gast)


Lesenswert?

Ach ja ein Code den ich beispielsweise parsen möchte ist der Folgende:
1
OBJECT1.ADD("register"=>"MeinRegister","value"=>OBJECT2.CALL("register"=>"AnderesRegister"));

von Karl H. (kbuchegg)


Lesenswert?

Farin schrieb:
> Hei zusammen
>
> Ich habe eine Frage zu dieser ANTLR-Grammatik. Ich habe jetzt alles als
> Lexer-Regeln eingebaut was aber offensichtlich nicht stimmen kann.

:-)
Wenns eh offensichtlich ist, wo liegt dann das Problem?


> Wie
> muss ich den Code umstellen dass er mir einen Parserbaum ausgibt. Ich
> hoffe ihr könnt mir helfen. :)

Du hast den Grundfehler Nummer 1 gemacht:
Zu viel auf einmal


Nochmal zurück an den Start und baue deine Grammatik schrittweise auf, 
wobei du jeden einzelnen Schritt testest.

von Farin (Gast)


Lesenswert?

Sehr geehrter Herr Buchegger

Genau darin liegt mein Problem. Lexer-Regeln zu bauen ist einfach. Das 
verstehe ich und habe ich schrittweise gebastelt. Wobei mir sich die 
Frage stellt wann der Lexer die Arbeit getan hat und der Parser anfangen 
muss den vom Lexer generierten Baum abzuarbeiten und zu parsen. Ich 
hoffe Sie können mir hier ein bisschen helfen und mich nicht zu dem 
ermuntern was mir ohnehin bevorsteht, nämlich die Grammatik neu zu 
schreiben.

Ich bin auf der Suche nach meinem Fehler und nicht nach Menschen die 
mich darauf hinweisen Fehler gemacht zu haben. ;-)

Ich hoffe das war nicht allzu offensiv ansonsten möchte ich mich dafür 
entschuldigen und Sie, Herr Buchegger, noch einmal höflichst um ihr 
Fachwissen und den damit verbundenen technischen Beistand in meiner 
Notlage bitten.

Mit freundlichen Grüssen

Der Farin

von Auch Hans (Gast)


Lesenswert?

Ist zwar etwa her, dass ich aktiv mit ANTLR gearbeitet habe, aber ich 
würde mal sagen, dass das hier
1
Identifier      : Alpha AlphaNum*;
keine Lexer Rule ist, sondern eine Parser Rule.

Ansonsten baut der Lexer keine Bäume. Das macht der Parser. Der Lexer 
zerlegt den Quelltext nur in (quasi atomare) Elemente, aus denen der 
Parser mit den entsprechenden Regeln dann z.B. einen Abstract Syntax 
Tree bauen kann. Der kann dann von einem zweiten Parser abgearbeitet 
werden.

Um einen AST zu bekommen musst du output=AST oder so in die options 
schreiben.

Was möchtest du denn eigentlich genau bauen? Und hast du schon mal was 
mit Lexern/Parsern gemacht?

Grüße,
der, der auch Hans heißt

von Farin (Gast)


Lesenswert?

Hallo anderer Hans ;-)

Ich habe jetzt angefangen die Grammatik umzuschreiben. Leider habe ich 
bisher nur 2 Compiler auf Basis einer for-Schleife mit If-Konstrukt und 
einem Regex-Baum gebaut. Da beide Programme nicht das gemacht haben was 
sie wirklich sollten und mit der Zeit relativ unübersichtlich wurden 
habe ich mich entschieden, auf den Anstoss eines Kollegen, mit ANTLR zu 
arbeiten.

Ich will einen Parser für eine eigene Sprache bauen wie sie in dem 
Codebeispiel dokumentiert ist. Dass ganze soll dann in ein existierendes 
Programm(c#) eingebaut werden um gewisse Abläufe am PC zu 
automatisieren.

Momentan bin ich soweit, dass mir der Lexerteil des Codes, so wie ich 
das verstanden habe, prüft ob die Eingaben die richtigen 
Zeichenabfolgen, etc. haben und die zu ganzen Wortteilen 'kompiliert' 
die dann der Praser wiederum in einen AST zusamensetzen soll.  Ist das 
so richtig?

Somit bin ich zwar ein Anfänger mit Lexern und Parsern möchte aber 
dennoch damit arbeiten, da die anderen meiner Lösungsansätze mich nicht 
zufriedenstellen konnten.

Danke schon mal für die erste Hilfe anderer Hans :)

Gruss Farin

von Auch Hans (Gast)


Lesenswert?

Hi,

AntLR ist natürlich nicht gerade der einfachste Parser-Generator zum 
Einstieg. Die Theorie kannst du schön kompakt in der Bison Doku 
nachlesen. Der funktioniert zwar anders als AntLR, aber Lexer und Parser 
sind dort sehr gut erklärt. Bei AntLR solltest du das Buch vom AntLR 
Autor kaufen. Lohnt sich definitiv.

Ansosnten ist der Ablauf wie folgt:
Lexer -> zerlegt Text in Tokens (Identifier, Zahlen, evtl. 
Schlüsselwörter usw.)
Parser -> Versucht in den vom Lexer gelieferten Tokens die von dir 
definierten Regeln wiederzufinden. Wenn du möchtest liefert er auch 
einen AST als Ergebnis.
TreeWalker -> Wäre dann z.B. der zweite Parser, der den AST durchläuft 
und dann irgendwelche Aktionen ausführt.

Du solltest dir auch unbedingt AntlrWorks installieren. Das ist eine 
praktische Workbench zum Arbeiten mit AntLR Grammatiken.

von Farin (Gast)


Lesenswert?

Nochmal ein freundliches Hi an den Hans #2 :)

Mittlerweile hab ichs gelöst und mein Parser ist fertig. Hat zwar ein 
bisschen gedauert aber je mehr ich mich einfach dazu überwunden habe 
alles zu löschen und von vorner mit Lexerregeln einfache Datentypen 
abzuhandeln hat es je mehr desto besser funktioniert und ich habe 
endlich verstanden was ich tun muss damit ich das zufriedenstellende 
Resultat finde.

Danke vielmals für deine Hilfe und zu deinen Punkten:
1-3) Habe ich verstanden. Nummer 3 werde ich nun so wie ich das jetzt 
habe ich C# programmieren da dieser dann den effektiven Programmablauf 
bestimmt.

Die ANTLRworkbench hab' ich installiert und ich finde sie sehr passend. 
Meine Erkentnisse etc. habe ich hier festgehalten. => 
http://blog.farin.ch/?p=382

Dort werde ich auch wahrscheinlich eine Tutorialserie für ANTLR 
schreiben da mich das Thema sehr interessiert. Das Buch von Terence Parr 
habe ich übrigens schon hier, von meinem Kollegen erhalten. :)

Nochmal Danke für deine Hilfe.

Farin

von Auch Hans (Gast)


Lesenswert?

Hi,

hier noch ne kleine Anmerkung zu deinem Blog:
1
Wie oft die Zeichen dargestellt werden, etc. MUSS zwingend dem Parser überlassen
Das stimmt so nicht. Es ist sinnvoller, wenn nicht sogar zwingend 
notwendig, daß der Lexer mehrere Zeichen zu einem Token zusammenfügt. 
Denn wenn du dem Parser irgendwann sagst, daß Whitespaces ignoriert 
werden sollen, würden folgende Codezeilen das gleiche Ergebnis liefern:
1
12 34
2
1234
Der Lexer würde 4 Tokens hintereinander liefern, die der Parser dann z 
einer Number zusammensetzt.
Bei der Lexer Rule
1
NUMBER : '0'..'9'+;
würde er im ersten Fall zwei Token (nämlich 12 und 34) und im zweiten 
Fall ein Token (1234) zurückliefern.
Typische Lexer Token sind halt sowas wie:
- INTEGER    '0'..'9'+
- IDENTIFIER 'a'..'z' ('a'..'z' | '0'..'9' | _)*
- STRING     '"' .* '"'
Ich hoffe die Syntax stimmt. Hab ich mal aus dem Kopf hingeschrieben.

Grüße!

von Auch Hans (Gast)


Lesenswert?

Achja...

den TreeWalker würde ich auf jeden Fall auch mit AntLR bauen...ist nicht 
trivial, aber wird einfacher als das manuell zu machen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.