[linux-l] Grammar Design

Volker Grabsch vog at notjusthosting.com
So Sep 18 21:58:42 CEST 2005


On Sun, Sep 18, 2005 at 11:35:48AM +0200, Oliver Bandel wrote:
> Naja, im Moment bin ich da noch ein bischen am herum probieren.
> 
> Will DSLs implementieren, in welcher Art... da schaue ich noch.

Werde mal bitte konkreter.

Bei mir gehen nämlich gerade die Alarmglocken an, dass du ein Problem
lösen willst, dessen sich schon andere angenommen haben. Dann könnte
deine Lösung an NIH erkranken.

> Welche Art von Parser/Grammatik liegt denn HTML/XML zugrunde?
> Mit lex/yacc kann man das ja auch noch bearbeiten.
> oder gibt es da schon besseres?

Na klar. Es gibt HTML- und XML-Parser. Bei den XML-Parsern gibt's
sogar Standard-APIs, und zwar:

* SAX (für serielles Parsen)

* DOM (alles in den Speicher laden und dann in der Baumstruktur
       rumwandern)

Solche Parser-Libs findest du für alle gängigen Sprachen. Mir
persönlich gefällt da übrigens "libxml2" (im GNOME-Projekt entstanden)
am besten. Es ist ne C-Library, sauschnell, und es gibt Wrapper
für alle möglichen Sprachen (Python, Ruby, ...)

> Naja, ganz krass wird es natürlich, wenn man - z.B. für
> Literate Programming Tools - verschiedene Kontexte hat,
> in denen anders geparst/gelext(gescannt) wird.

In so einem Fall ist es am besten, für die "Haupt-Sprache" (die
alles zusammenhält, ich vermute mal: XML) einen eigenen Parser
zu nehmen, und die "Bruchstücke" dann durch ihre jeweils eigenen
Parser nochmals zu jagen.

> Dann müsste der lexer sich der Umgebung anpassen,
> in der geparst wird...
> ...welcher Art Grammatiken ist das?

Wenn sich die Sprachen "vertragen", dann immer noch LR1.
Ansonsten gibt es dafür irgendeine allgemeinere Sprachklasse,
die aber dann nicht mehr viel aussagt.

> Kann mir zwar denken, daß zu programmieren, aber welcher
> Art Grammatik das ist, weiß ich nicht.
> Vielleicht gibt's da ja schon fertig-Tools für?
> (bezweifle ich aber... erst mal).

Ich vermute, dass es sogar Tools gibt, die dein gesamtes Problem
lösen. Nenne mal bitte 2 oder 3 Beispiele, konkrete Anwendungsfälle.
Wo siehst du ein Problem, wie willst du es lösen?

Eine extra neue Sprache ist i.A. keine gute Idee mehr. Schon gar
nicht heutzutage, wo es schon viel zu viele ähnliche Sprachen gibt.

Nur, wenn du etwas *wirklich* Neues, Innovatives baust, dann
könnte sich eine neue Sprachen lohnen. Aber selbst in diesem Fall
wirst du dich in gewisser Form an existierende Sprachen und
Paradigmen halten müssen, sonst droht das NIH-Syndrom.

> Das bedeutet aber für den Anwender der Sprache, daß er/sie/es diese
> komplexe Sprache können müsste.
> 
> Ich finde aber, es macht keinen Sinn, eine DSL zu implementieren,
> die einen bestimmten zweck erfüllen soll und dafür dann noch eine
> allgemeine Programmiersprache verstehen zu müssen.
> 
> Das ist dann doch nur was für Programmierer, aber nicht für
> Normalmenschen eines speziellen Anwendungsgebiets.
> Da sollte schon was eigenständiges kreiert werden,
> so daß die Benutzer nur in Ihrem Fachgebiet sich auskennen müssen
> und dennoch ihre eigenen Skripte schreiben können.
> Das ist ja der Sinn einer DSL (neben anderen Vorteilen).

Eine DSL sollte immer möglichst einfach sein. Aber was heißt schon
"Domain Specific"? Meines Wissens nach sind die meistens "Domains"
schon abgegrast.

Nenn doch mal bitte konkrete "Domains", in denen du etwas vermisst.
Deine hier genannten Beispiel ist eher Negativ-Beispiele, wo du
keine neue Sprache erfinden solltest.

> So daß man in eingermassen verständlichen Anweisungen
> die Filter definieren kann, und man bekommt ein Websieve-Script heraus.

Websieve kenne ich nicht, aber allgemeine Filtersprachen wird es wohl
schon lange geben.

Falls es "einfach" sein soll, ist wohl eine Art "Konfiguration" gefragt,
die viele Standardfälle abdecken kann. Konfigurations-Sprachen gibt's
aber auch genug. Genauer gesagt: Sprachen, die hierarchisch aufgebaute
Datenstrukturen darstellen.

Eine davon ist XML. Die ist aber nur sinnvoll, wenn du Text hast, der
durch Sub-Elemente ("Tags") unterbrochen werden soll. Ist hingegen deine
kleinste Einheit schon der Text (bzw. Zahlen), dann solltest du zu einer
Sprache greifen, die leichter zu parsen /und/ menschenfreundlicher
(d.h. editorfreundlicher) ist, z.B.:

* YAML
   (gibt's dafür schon ordentliche Parser? Hab bisher nur Schrott gefunden)

* JSON
   (ist okay, hat aber IMHO den gleichen Nachteil wie YAML: es ist
    typisiert. Das finde ich grundsätzlich bedenklich, und würde
    auch diskutieren, wenn jemand anderer Meinung ist.)

* INI-Dateien 
   (sehr portabel, es gibt gute Parser, nicht-typisiert,
    einziger Nachteil: hat nur zwei Hierarchie-Ebenen)

* S-Expressions
   (sieht sehr nach "Lisp" aus, aber wenn deine Daten sowieso nur max.
    drei Hierarchie-Ebenen haben ("einfache" Sprachen brauchen nur selten
    mehr), dann halten sich die Klammern in Grenzen. Übersichtlicher als
    XML ist es allemal, und wunderschön zu parsen, d.h. Parser gibt's
    genug)


In jedem Fall brauchst und solltest du keinen eigenen Parser schreiben.

> Oder halt für andere beknackt gemachte Eingabesprachen.
> Leider denken viele Programmierer nicht an die Anwender und machen
> eigentlich leichte Sachen unnötig kompliziert in der Benutzung.
> Oder lassen komplizierte Sachen auch kompliziert fpr den Anwender,
> statt eine einfache benutzerschnittstelle zu schaffen.

Das kannst du Programmierern nicht immer vorwerfen. Es ist ein großes
Design-Problem. Die Begriffe, die du hier anbringst ("einfach" -
"kompliziert"), sind z.T. sehr subjektiv, und abhängig vom eigenen
Wissensstand. Du kannst versuchen, möglichst viele Standard-Fälle
mit "einfachen" Konstrukten abzudecken, aber dann hast du ein Problem,
die Nichtstandard-Fälle sauber abzudecken. Hältst du deine Konfiguration
für diesen Zweck aber flexibel genug, willst du es den Leuten nicht
zu schwer machen, also hältst du deine Sprache konsistent. Wenn dir
dann dieser Spagat gelingt, und deine Konfiguration konsistent für
alle Anwendungsbereiche ist, dann sind dir zwar die Leute mit den
Nichtstandard-Problemen sehr dankbar, aber die Anfänger meckern wieder
herum. Diese wissen die Konsistenz nicht zu schätzen, weil sie die
größeren Zusammenhänge nicht erkennen und sich auch nicht anlesen
möchten. Davon abgesehen gelingt es aber den wenigsten, ihre
Konfiguration konsistent zu halten.

Zwei völlig unterschiedliche Wege, diesen "Spagat" zu bewältigen, sieht
man bei den Mailservern Exim und Postfix. Beide sind IMHO sehr gut und
decken das Anwendungs-Spektrum voll ab. Dennoch sind beide
Konfigurationen immer noch zu kompliziert für Leute, die keine Ahnung
vom Mailsystem haben.

Für einen Mail-Administrator ist "RTFM" dann in jeden Fall
gerechtfertigt. Aber ein Anfänger, der vielleicht wirklich nur eine
Standardlösung will, sollte sich damit nicht zu sehr rumärgern müssen.
Das Debian-Projekt hat ja mit seinem Interface "exim-config" dahingehend
einen guten Schritt gemacht: Es werden wenige, einfache Fragen gestellt,
und danach eine Exim-Konfigurationsdatei daraus gebaut.

> Deswegen fallen mir andauernd Sachen ein, die man diesbeztüglich
> zusammen bauen könnte, auch wenn es dann oftmals bei der Idee bleibt.

Der Teufel steckt wirklich im Detail. Wenn du diese sog.
"Vereinfachungen" einfach aussummierst, ohne dir ein wirklich geniales
Konzept dahinter zu erarbeiten, verschiebst du womöglich nur die
Probleme, indem einfache Sachen noch einfacher werden, aber die
komplexen Dinge unerträglich oder gar nicht mehr zu tun sind. Du
bekommst mehr Feature-Wünsche, und irgendwann wird deine Sprache
wahrscheinlich noch viel wüster, als die ursprüngliche Sprache, die
du vereinfachen wolltest. Das ist das NIH-Syndrom.

Ich denke, der Weg wie bei Exim ist der einzig sinnvolle: Man hat
eine stark vereinfachte Konfigurations-Sprache, die gerade so die
gängigen Standardfälle abdeckt, aber nicht mehr! Und dann noch eine
konsistente, wohldurchdachte "richtige" Konfigurations-Sprache, die
alles abdeckt. Die "einfache Konfiguration" ist für Anfänger, und
man sollte sie in die "richtige Konfigurationssprache" umwandeln können,
um sie dann den gehobenen Wünschen anzupassen, die man sowieso nur
konfigurieren sollte, wenn man Ahnung von der Materie hat (d.h. das
fu***** Manual gelesen hat).

Meist reichen hierzu Templates, d.h. auch dafür brauchst du keinen
Parser, denn Templating-Systeme gibt's ebenfalls genug.


> Aber das eine oder andere krassere teil schwebt mir da schon 
> immer wieder im Kopf rum (z.B. auch Literate programming Tools).

Gibt's schon. Auch hier: Wenn du was vereinfachen willst, nimm eine
möglichst einfache Eingabesprache (ich bin für INI-Dateien, aber
XML, YAML oder JSON tun's auch), und der Rest ist Aufgabe eines
Template-Systems.

Übrigens ist es das, was (bezogen auf System-Administration) mit
SuSEconfig probiert wurde, mehr oder weniger erfolgreich, da gehen
die Meinungen auseinander.

> Derzeit überlege ich, ob ich das Tool (Laban Scale Generator,
>   siehe http://me.in-berlin.de/~first/labscalgen-invoke.cgi)
> nicht doch eher HTML-/XML/LaTeX-like umbaue.

Wozu braucht man diese Laban-Symbole eigentlich? Ein Link zu deine
Seite mit Erklärungen (Wikipedia?) auf der Homepage wäre nicht schlecht.

Ich rate zu folgender Vorgehensweise: Schau, ob es für diese
Laban-Symbole nicht schon ein Standard-Dateiformat gibt. Falls ja,
hat eine Unterstützung dieses Formats (mindestens als Export) höchste
Priorität.

LaTeX-Support wäre am besten in Form eines LaTeX-Paketes, welches
diese Symbole bereit stellt, z.B. in Form von Makros. Was du dann
als LaTeX-Code generierst, sollte dieses Paket dann einfach benutzen.
Alternativ wäre eine Inline-Version natürlich auch gut. Es würde mich
aber wundern, wenn es diese Symbole nicht schon längst in LaTeX bereits
gäbe, sodass du direkt ein existierendes Paket benutzen kannst.

Deine Scriptsprache halte ich für nicht unbedingt nötig.


1. Fall:
--------

Wenn du "Scipting"-Fähigkeiten willst, wieso nimmst du dann nicht
eine Scriptsprache. z.B. in Python könnte das so aussehen:

Du schreibst ein Modul "laban.py", dann könnte dein Script so aussehen:


from laban import *

print(title, "Example of generated Scales")
print(scale, D, R, H, DRF)
newline()
print(scale, F, B, R, L, H, D, RF, RB, LF, LB, HF, HB, DF, DB, HR, HL,
             DR, DL, HRF, HRB, HLF, HLB, DRF, DRB, DLF, DLB)
newline()
print(flipRL, scale, F, B, R, L, H, D, RF, RB, LF)
newline()
print(flipFB, scale, F, B, R, L, H, D, RF, RB, LF)
newline()
print(flipHD, scale, F, B, R, L, H, D, RF, RB, LF)

[...]


Naja, ist noch nicht schön, ich willte nur das Prinzip verdeutlichen.
"Sicher" ist das natürlich nicht, aber wenn es ne Scriptsprache werden
soll, ist sowieso Vorsicht angesagt, da ist es IMHO besser, gleich von
vornherein die Karten auf den Tisch zu legen ("das ist einfach nur
beliebiger Python-Code"), als eine nichtvorhandene Sicherheit zu
suggerieren.

Auf jeden Fall hättest du Schleifen, etc. schon geschenkt bekommen.
Vielleicht würde der Kram in Lisp, Ruby oder Haskell sogar noch schicker
aussehen. Einen eigenen Parser brauchst du jedenfalls nicht, und auch
keine eigene Sprache.


2. Fall:
--------

Willst du keine Scripting-Fähigkeiten, dann kannst du z.B. S-Expressions
nehmen (bin mir nicht mehr ganz sicher):

(print title "Example of generated Scales")
(print scale D R H DRF)
newline
...

Bis auf diene Variablenzuweisung hättest du alles intus. (fügst du
dann noch einen (let A B)-Befehl hinzu, und gehst konsequent weiter,
landest du übrigens bei Lisp oder Scheme).  Natürlich wären JSON oder
XML prinzipiell ebenfalls geeignet.

Auch hier brauchst du keinen eigenen Parser und keine eigene Sprache.


3. Fall:
--------

Du willst ein Zwischending zwischen 1. und 2.  ... in dem Fall: Vergiss
es, du wirst eine eigene Sprache beginnen, immer mehr Features reinnehmen,
das Ding wird sich zu einer Scriptsprache aufplustern, die man extra
lernen muss, und jeder wird sich ärgern, wieso das später so "eigenartig"
(d.h. aus der Sicht von anderen: "umständlich") ist. Das NIH-Syndrom eben.

Entweder du sagst von vornherein, dass du nur ganz, ganz wenige Features
willst. Dann kannst du sie sauber aufbereiten und in XML, YAML,
S-Expressions, ... verpacken. Dann hast du ne Beschreibungssprache.

Oder willst eine Scriptsprache. Dann nimm doch einfach eine, die dir
gefällt, und schreibe eine Modul dafür. Um Kontrollstrukturen etc.
brauchst du dich dann gar nicht mehr zu kümmern, du bekommst so viel
geschenkt! Und außerdem ist es dann leichter für andere, deine Script-
Sprache zu lernen, weil sie vielleicht Python (oder was auch immer du
nimmst) schon kennen.

Von einem Kuddelmuddel dazwischen kann ich nur abraten.


> Das war in derzeitiger Version erst mal nur ein Start-Teil,
> ein Erstversuch.  Aber einer, den man schon benutzen kann.
> 
> Immerhin kann man da nun auch Variablen setzen usw.

Da fängt's an.
Vielleicht noch Schleifen?
Wenn-Dann-Bedingungen?
...

du landest bei einer Scriptsprache. Eine mit anderer Syntax, die
wahrscheinlich erstmal nicht koherent sein wird, weil historisch
gewachsen. Du wirst später deine Sprache neu designen, und beim
Aufräumen feststellen, dass es wie Pyhton/Haskell/LaTeX/...
aussieht. Diesen gesamten Gedankengang haben schon Leute vor dir
gehabt. Auch sie wollten es stets möglichst einfach und übersichtlich
halten.

Such dir eine schöne Sprache, und nimm diese als Basis für deine
Überlegungen. Alle bisherigen Sprachen als "zu kompliziert" oder
"anfängerunfreundlich" abzustempeln ist ziemlich arrogant, und
meiner Meinung nach überhaupt nicht der Fall.

> Aber viell. wäre eine andere Syntax/Grammatik besser.

Warum nicht gleich eine andere *Sprache*?
Warum nicht gleich eine schon existierende Sprache?

> Wird viellicht "inspired by" LaTeX, HTML/XML oder so.
> Aber soll auch Möglichkeiten wie Makros/prozeduren/Funktionen zulassen.

Nein, *nimm* LaTeX oder HTML/XML oder eine andere geeignete Sprache, und
*erweitere* sie. Wenn deine Sprache wächst, wird sie ohnehin an Komplexität
zunehmen. Dann nimm lieber gleich ein etwas komplexeres System, da weißt du
zumindest, dass du dich nicht verrennen wirst. "Yet another language" ist
wirklich keine gute Idee. Du wirst viel Zeug nachimplementieren,
wahrscheinlich in schlechterer Qualität, das es längst in den anderen
Sprachen gibt.

Wenn du kein umwerfend neues Konzept für deine Sprache hast (und danach
sieht dein Code nun wirklich nicht aus - alles altbekannte Konstrukte),
dann entwickle auch keine neue Sprache!

> Bin kein XML-Spezi, denke aber, Sachen wie Variablen
> funktionieren damit nicht. Und spätestens bei Prozeduren/Funktionen/Makros
> ist da wohl Schicht.  Also muß was eigenes her.

Also "1. Fall". Und nein, wieso immer was eigenes, wieso nicht
Existierendes wiederverwenden und verbessern? Da hast du mehr davon,
und auch die Allgemeinheit.

Der Stempel "selbstgemacht" zeugt nicht von Qualität. Das existierende
auf intelligente Weise zusammenarbeiten lassen, *da* liegt wahre
Leistung. Bisherige Ergebnisse wiederzuverweden ist genau das, woran
es derzeit mangelt. Es gibt keinen Mangel an Sprachen, und auch nicht
an allem möglichen selbstgemachten genialem Zeug, das irgendwo rumliegt
und vergammelt. Warum? Weil viel zu wenige die guten Ideen ihrer
"Vorgänger" aufgreifen und verbessern, sondern viel zu viele unbedingt
von Null anfangen wollen, weil "selbstgestrickt" ja "cooler" ist, und
weil's besser für's Ego ist.

> Gestern Abend hatte ich da schon Ideen zu. Soll ja auch für Normalanwender
> verstehbar bleiben, also muß ich immer abwähgen zwischen "läßt sich
> prima implementieren", "ist sehr leistungsfähig" und "bleibt für
> nicht-programmierer noch verständlich".

Scriptsprachen sind auch für nicht-programmierer verständlich. Wenn
du deine eigene Scriptsprache schreibst, dann riskierst du nur, dass
der Anwender doch zum Programmierer wird. Nimm folgendes Ruby-Programm:

	puts "Hello World"
	3.times do
	    puts "XXX"
	end

Auch den Normal-Anwender wird es nicht überraschen, wenn dort jetzt:

	Hello World
	XXX
	XXX
	XXX

.. rauskommt. Oder dasselbe in Python:

	print "Hello World"
	for i in range(3):
	    print "XXX"

Ich vestehe da echt dein Problem nicht. Du tust so, als wäre es
heutzutage sonstwas von kompliziert, einfache Programme zu schreiben.
Das ist aber überhaupt nicht der Fall. Im Gegenteil: Für jeden Geschmack
ist mittlerweile was dabei. Und das war vor 10 Jahren übrigens auch
schon so, nur dass damals die Sprachen noch weniger ausgereift waren.


Achso, fällt mir grad ein: Wenn dir LaTeX zu kompliziert ist, du aber
eine Dokumentensprache willst, schau dir auch mal "lout" an, welches
hier auf der Liste schonmal angesprochen wurde:

	http://snark.ptc.spbu.ru/~uwe/lout/lout.html


Du hast bisher jedenfalls keine Idee oder Konzept genannt, welches eine
neue Sprache notwendig oder auch nur sinnvoll erscheinen lässt. Alles
altbewährtes Zeug, das du nur zusammenbacken brauchst.


Viele Grüße,

	Volker

-- 
Volker Grabsch
---<<(())>>---
Administrator
NotJustHosting GbR



Mehr Informationen über die Mailingliste linux-l