Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Julién

Alter Hase

  • »Julién« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

1

20.10.2015, 21:34

EBNF zu Code

Wir nehmen gerade in der Schule (12.Klasse, Bayern) formale Sprachen durch.
Leider kommt die Implementierung zu kurz.
Tatsächlich frage ich mich wie man denn einen Lexer/Parser auf Basis einer Menge EBNF Regeln implementieren kann.
Nehmen wir doch mal an an, wir hätten folgende Regeln (aus dem Buch übernommen):

C-/C++-Quelltext

1
2
3
 ZifferNN = "1" | "2" | ... | "9".
 Ziffer = "0" | Ziffer.
 NatürlicheZahl = ["-"] ZifferNN {Ziffer}


Ich muss zugeben, dass es komplexere Regelwerke gibt, aber ich will es abends dabei belassen. Wie würde man sowas jetzt zum Beispiel in C++ implementieren?
Mein Ziel ist es eine einfache (vgl. David's Skriptsprache aus SpPro mit DX9), typisierte (int & float) Skriptsprache zu implementieren.

Zusatzfrage:
Kann man Einrückungen á la Python irgendwie über die EBNF darstlellen?

Mit freundlichen Grüßen,
Julien

P.S.: Bitte keine Antworten wie "nehme einfach ANTLR". Ich würde gerne verstehe wie ich Strings auf Basis dessen verarbeiten kann.
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

2

20.10.2015, 21:48

Ich habe vor einigen Jahren mal YAPPS fuer Python benutzt, es generiert Python Code fuer einen Parser aus einer Grammatik Definition die sehr aehnlich zu EBNF aussieht.

Du koenntest nen simplen Parser damit generieren und dir anschauen wie der Code aussieht. Wenn ich mich recht erinnere ist der generierte Code sehr einfach zu verstehen.
http://theory.stanford.edu/~amitp/yapps/…nual/node1.html

PS: Es sieht so aus, als sei ANTLR auch ein Parser Generator. Du kannst dir auch anschauen wie der generierte code von denen aussieht.

3

20.10.2015, 21:58

Boost::Spirit ist auch recht nützlich.

4

20.10.2015, 22:27

Das ist nicht trivial und eine ganze Ecke schwieriger als einen Zustands-Automaten zu einem regulären Ausdruck zu implementieren. Aber folgendes Skript scheint einen guten Überblick über die Theorie zu geben:

http://amor.cms.hu-berlin.de/~kunert/papers/lr-analyse/

Willst du einfach nur einen Parser zu einer Sprache haben, ohne notwendigerweise die Implementierungsdetails zu verstehen, sind die angesprochenen Generatoren aber sicherlich eine gute Anlaufstelle.
Lieber dumm fragen, als dumm bleiben!

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

5

20.10.2015, 22:39

Boost::Spirit ist auch recht nützlich.

Uii... hast du Spirit schonmal benutzt? Ich habe vor ein paar jahren mal damit gearbeitet um eine CSS-ähnliche Sprache zu parsen und ja es hat zum Schluss funktioniert... aber ich würde is niemandem empfehlen (es sei denn es ist eine sehr einfache Grammatik). Die Zeit zum Kompilieren einer Datei die spirit benutzt ist mindestens 10 mal so hoch wie die einer normalen datei. Und wenn du einen Fehler machst bekommst du 1000 Zeilen Fehlermeldung (für einen fehler... und der eigentliche Grund ist darin irgendwo versteckt... nicht am anfang und auch nicht am Ende). Rückblickend war es der mein größter Fehler den ich je beim proggen gemacht habe boost::spirit zu verwenden. Hier eine Codedatei aus besagtem Projekt :)

PS: ihr dürft mich nicht falsch verstehen... boost::spirit ist das coolsten meta-template projekte überhaupt und ich finde die Idee und die Umsetzung super.... nur für große Grammatiken ist es einfach nicht geeignet

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

20.10.2015, 23:46

Dein Beispiel ist ja gar nicht so schlecht. Lieber erst mal einfach anfangen. Ich würde dir vorschlagen sogar erst mal auf einfache BNF zurück zu greifen. Fürs parsing gibt es verschiedene Ansätze. Möchtest du das ganze von Hand schreiben würde sich ein Top Down Parser anbieten. Das kannst du relativ einfach realisieren wenn du pro Regel eine Funktion bastelst. Du hast ja irgendeine Startregel. Das ist deine Startfunktion. Diese prüft im Prinzip das erste Zeichen (besser als Zeichen wären an sich Tokens, dafür würde man normalerweise einen Lexer schreiben um das ganze einzuteilen). Je nach Token leitet diese Funktion dann passend weiter an weitere Funktionen. Die Funktionen lesen dann an sich Terminale ein. Ein Terminal ist im Prinzip ein Zeichen/Token welches direkt verarbeitet wird und keine extra Regel ist. Je nachdem rufst du weitere Regeln auf was wieder einfachen Funktionsaufrufen entspricht. Guck dir doch vielleicht mal LL1 Grammatiken an. Damit kann man eigentlich relativ gut starten. Für den Anfang bietet es sich an einen Parser für Terme oder vergleichbares zu schreiben. Kannst ja mal einen Taschenrechner schreiben welcher von dir eingetippte Ausdrücke auswertet. Das ganze kann man dann natürlich mit allerlei Funktionen erweitern.
Hier wirklich ausführlich auf den Stoff einzugehen sprengt ein wenig den Rahmen. Kannst mich aber gern mal anschreiben wenn du ein wenig Hilfe benötigst.
Was die Einrückung von Python angeht. Im Prinzip wird der Code zuerst in Token unterteilt. Dabei könnte ein Tab bzw mehrere Leerzeichen als einzelnes Token angesehen werden. Diese könnten dann vom Parser als Codeebene ausgewertet werden. Im vergleich nutzen andere Sprachen Klammern wie du weißt. Das ist für den Anfang auf jeden Fall simpler, das mit den Tabs oder Leerzeichen geht an sich aber auch. Das theoretische Modell hinter Parsern sind Kellerautomaten. Guck dir die vielleicht einfach mal an. Eine simple Aufgabe für einen solchen Automaten wäre zum Beispiel das zählen von Klammern, bzw die Verifizierung ob ein Ausdruck vernünftig geklammert ist. Du kannst dir ja mal überlegen wie man das ganze jetzt für Python umsetzen könnte.
Wichtig ist alt wirklich erst mal klein anzufangen. Nimm dir eine einfache Art von Grammatiken und versuche erst mal damit zu arbeiten. Und dann langsam Schritt für Schritt weiter arbeiten.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige

Ähnliche Themen