joetjen.net
EN DE
Grammatiksprache

Die Grammatiksprache Aether

Aether beschreibt eine Sprache vollständig in einer Datei: ihre Tokens, ihre Syntax, den Umgang mit Leerraum und welche Teile einer Übereinstimmung erhalten bleiben. Namen in Großbuchstaben sind Tokens, die ein Lexer erkennt; Namen in Kleinbuchstaben sind Regeln, die ein Parser über diesen Tokens erkennt.

Ichor 0.3

Ein erster Blick

Diese Grammatik liest eine kleine Einstellungsdatei — Zeilen der Form name = wert, mit Kommentaren:

settings.aether
@grammar "settings"
@root document
@skip TRIVIA

COMMENT := "#" (!"\n" .)*
TRIVIA  := (SPACE | COMMENT)*

TRUE   := "true"
FALSE  := "false"
NAME   := [a-z_] [a-z0-9_]*
NUMBER := DIGIT+
STRING := "\"" (!"\"" .)* "\""

document := TRIVIA? entry* TRIVIA?
entry    := key:NAME "=" value:value
value    := TRUE | FALSE | NUMBER | STRING
  • @grammar benennt die Grammatik und @root die Regel, bei der das Erkennen beginnt. Beide sind Pflicht, in dieser Reihenfolge.
  • @skip TRIVIA erlaubt Leerraum und Kommentare zwischen je zwei Teilen einer Regel.
  • COMMENT bis STRING sind Tokens. TRUE steht absichtlich vor NAME: Beide passen auf true, und das frühere gewinnt.
  • document, entry und value sind Regeln. Das "=" in Anführungszeichen wird ohne Deklaration zu einem eigenen Token.
  • key: und value: benennen die Teile eines Eintrags, auf die es bei der Weiterverarbeitung ankommt.
# service
port = 8080
debug = true
name = "api"
ok
true = 1
1:1: unexpected "true" -- did not expect more input here
1 | true = 1
  | ^

Gestaltung

  • Lexer und Parser in einer Datei. Die Schreibweise entscheidet, was was ist; eine getrennte Token-Datei, die man synchron halten müsste, gibt es nicht.
  • Immer zwei Stufen. Tokens nehmen die längste Übereinstimmung, Regeln die erste passende Alternative — jede Stufe behält ihre eigene einfache Regel.
  • Leerraum ist eine Einstellung, keine Fleißarbeit. Ein Pragma macht jede Regel tolerant dafür; ein Präfix verbietet ihn dort, wo zwei Teile aneinanderstoßen müssen.
  • Nur Syntax. Eine Grammatik sagt, was gültig ist, und benennt die Teile; was sie bedeuten, wird anderswo entschieden.
  • Notausgänge, deutlich markiert. Wo eine Sprache ihre Syntax mitten in der Datei ändert, übergibt @native ein Token oder eine Regel an handgeschriebenen Code.

Eckdaten

EigenschaftWert
Endung.aether
KodierungUTF-8; Namen sind ASCII, Zeichenketten und Klassen dürfen jedes Zeichen enthalten
Kopf@grammar "name", dann @root regel — Pflicht, in dieser Reihenfolge
Kommentare; bis zum Zeilenende
ErgebnisEin Lexer und ein Parser — standardmäßig PEG, auf Wunsch LR oder GLR
ImplementierungIchor, das .aether-Dateien kompiliert

In Aether geschrieben

GrammatikDefiniertGenutzt von
casc.aetherdas Konfigurationsformat CASC — Grammatikcooper
dxn.aetherdas DXN-Textformat — Grammatikdextrin
logos.aetherProlog-Quelltextlogos
xeger.aetherreguläre Ausdrückexeger
abnf.aether …ABNF, BNF, ISO- und W3C-EBNF und PEGIchors eigene Importer

Auf diesen Seiten

  • Aufbau — Kopf, Pragmas, Kommentare, Namen, Definitionen und vordefinierte Tokens.
  • Ausdrücke — Operatoren, Zeichenketten, Zeichenklassen, Wiederholung, Vorausschau und Regex-Literale.
  • Lexen und Parsen — längste Übereinstimmung, geordnete Auswahl, Leerraum, Erfassungen, Layout und Engines.
  • Notausgänge — @keywords, @refine und @native.
  • Grammatik — Aether in Aether geschrieben, und wo die Implementierung von der Referenz abweicht.