Laden...

"Compiler" für beliebig definierte Skriptsprachen

Erstellt von userid11997 vor 12 Jahren Letzter Beitrag vor 12 Jahren 1.903 Views
U
userid11997 Themenstarter:in
400 Beiträge seit 2008
vor 12 Jahren
"Compiler" für beliebig definierte Skriptsprachen

Moin,

unser neuestes Projekt ist ein altes Projekt in neuer Verpackung. Dabei handelt es sich um eine art "Compiler", der eine beliebig definierte Scriptsprache in ein unter C# verwend- und manupulierbares Konstruckt umwandelt, das im gleichen oder einem anderen Thread ausgeführt werden kann.

Definition beliebig definierbare Scriptsprache

Unter dieser Definition, die ich hier verwende, versteht man zur Laufzeit interprätierten Programmcode, dessen Zusammensetzung in Syntax und Funktionsumfang vom Anwender definiert wird.

Funktionsumfang

Der Funktionsumfang beinhaltet neben der definierbaren Sprache auch einige Methoden zur Kompilierung in ein binäres Assembly, sowie zum laden eines geeigneten Assembly in die Laufzeitumgebung.

Umfang des Customising

Der Umfang des Customising ist sehr üppig gestrickt, was aber auch bedeutet, dass die Schnittstellen sehr Abstrackt gehalten sind. Die einzigen von der Komponente mitgelieferten Funktionen sind:
*Das Zerlegen des Klartextes anhand der Sprachdefinition *Lokalisieren von Funktionen in der verwendeten Funktionsbibliothek

Alle weitren Funktionen wie etwa das stufenweise Weiterzerlegen von Übereinstimmungen in der Spezifikation bleibt dem Anwender überlassen.

Definition von Sprache

Die Definition einer eigenen Sprache ist in zwei Bereiche geteilt. Zum einen der Bereich der Syntax:

Die Syntax der zugrunde liegenden Sprache wird mithilfe eines EBNF Musters nach ISO 14977 definiert.
Wir haben die Norm zusätzlich noch um folgende gültige Tags erweitert:
*-- (name) Definiert den Beginn oder das Ende einer Tokengruppe *#(definition),(definition) Definiert einen Satz von Eigenschaften für ein Token

Zum anderen der Bereich Funktionsumfang und Klassenstrucktur:

Die Methoden und Klassen werden in C# Quellcode als Assembly mit entsprechenden Flags definiert. Der Compiler greift auf die Flags zu und findet auf diese Weise im Script verwendete Methoden.

Mögliche Einsatzgebiete

Die Einsatzgebeiete des Projektes sind vielfältig gefächert. Es kann überall da eingesetzt werden, wo Scripts oder dynamische Programmteile verwendet werden sollen oder müssen.

Wir verwenden das Projekt z.B. als Basis für unser MMO und dort speziell für Mapscripts und Eigenschaften von Gegenständen und Zauber.

Aber welche Vorteile soll das haben?

Dies ist eine berechtigte Frage. Die Verwendung ist erstmal Aufwändig mit der definition einer eigenen Sprache und der Ergänzung wichtiger Interpeterteile und sicherlich gibt es für Sprachen wie Python, Lua etc. auch schon fertige und optimiertere Bibliotheken.

Unser Projekt kann aber mit einer sehr guten Performance, was oft bei größeren Scripten oder langsameren Rechnern ein Problem darstellen kann, aufwarten. Die Ausführungszeit unterscheidet sich nur unmerklich von echtem C# Programmcode.

Unser Projekt produziert zudem keine Laufzeitinterprätation anhand von Text, sondern eine Call-to-Call Strucktur, welche zu jedem beliebigen Zeitpunkt an jeder beliebigen Stelle betreten werden kann. Das heißt im Klartext, dass das Script z.B. beim Laden einer Map kompiliert wird und danach zu jedem beliebigen Zeitpunkt und beliebig oft ohne erneutes interprätieren ausgeführt werden kann.

Ein zusätzlicher Vorteil ist ausserdem ein voller reflektiver Zugriff auf nahezu alle Levels des Scripts und ein dadurch auch nach dem kompileren garantierten programatischen Modifikationsschema.

Eine daraus resultierende weitere Funktionsmöglichkeit ist z.B. einfache implementierung von Ereignisbehandlung anhand von Scripten (Spieler X wird mit Zauber Y gezielt, trägt aber Gegenstand Z mit Eigenschaft Q)


Im Testprojekt findet Ihr sowohl eine Definition einer simplen Sprache, die bislang nur den Befehl "print(parameter)" kennt, als auch ein Beispielprogramm welches Code anhand der Spezifikation "compiliert" (siehe Screenshots)

Auch mag am Anfang die atomare Opperationsstrucktur der Resultate etwas verwirrend sein, das Ganze hat aber durchaus seinen Sinn.

Wichtig

An der Importfunktion des ScriptProcessor wird mommentan noch gearbeitet.

U
userid11997 Themenstarter:in
400 Beiträge seit 2008
vor 12 Jahren

Und hier ein Screenshot mit geöffnetem Call-To-Call Baum

U
userid11997 Themenstarter:in
400 Beiträge seit 2008
vor 12 Jahren

Hier das Beispielprojekt. Für den Zerlegevorgang werden Tokens aus der Gruppe Compiler verwendet, für den Nachbearbeitungsvorgang Tokens aus der Gruppe PostCompiler.

Tokens mit der Eigenschaft NoParse werden beim Parservorgang zwar berücksichtigt, aber nicht aufgeführt.

U
userid11997 Themenstarter:in
400 Beiträge seit 2008
vor 12 Jahren

Neue Version:

Fertiggestellter ScriptProzessor interpätiert binäres Assembly in eine ausführbare Strucktur

Erzeugen von Handles wurde gefixt

Bugreports ausdrücklich erwünscht