joetjen.net
EN DE
Grammatiksprache

Aufbau einer Datei

Eine Grammatikdatei besteht aus einem Kopf und Definitionen. Der Kopf benennt die Grammatik und ihre Startregel und setzt grammatikweite Optionen; jede Definition gibt einem Token oder einer Regel ihren Rumpf.

Ichor 0.3

Kommentare

Ein ; beginnt überall in der Datei einen Kommentar bis zum Zeilenende. Blockkommentare gibt es nicht. Leerzeichen, Tabulatoren und Zeilenumbrüche trennen die Teile einer Grammatik und bedeuten sonst nichts — eine Definition darf sich über beliebig viele Zeilen erstrecken.

Namen

SchreibweiseDeklariertBeispiele
[A-Z_][A-Z0-9_]*ein TokenNUMBER DQ_STRING _WS
[a-z][a-z0-9_-]*eine Regelexpr map_entry key-path

Jede andere Schreibweise ist ein Fehler, keine dritte Art von Namen:

Foo := "a"
3:1: invalid identifier "Foo" -- must be ALL_UPPERCASE (a token) or snake_case/kebab-case (a rule)

Definitionen

Eine Definition ist ein Name, := und ein Ausdruck. Ein Abschlusszeichen gibt es nicht: Eine Definition endet dort, wo das nächste NAME := beginnt. Definitionen stehen in beliebiger Reihenfolge, und ein Rumpf darf einen weiter unten deklarierten Namen verwenden. Einen Namen doppelt zu deklarieren oder einen nie deklarierten zu verwenden ist ein Fehler:

a := "a"
a := "b"
4:1: rule a is already declared
a := b
3:6: reference to undefined token or rule :b

Unter Tokens zählt die Reihenfolge trotzdem, denn sie entscheidet Gleichstände im Lexer — siehe längste Übereinstimmung.

Vordefinierte Tokens

TokenStandard
DIGIT[0-9]
ALPHA[a-zA-Z]
ALNUMDIGIT | ALPHA
SPACE[ \t\r\n]
HEX[a-fA-F0-9]

Alle fünf gibt es in jeder Grammatik ohne Deklaration. Jedes darf neu deklariert werden, aber nur vor seiner ersten Verwendung — und @skip SPACE, ob geschrieben oder mitgedacht, zählt als Verwendung. Diese Grammatik verengt SPACE auf Leerzeichen und Tabulatoren; ein Zeilenumbruch ist damit kein Leerraum mehr:

@grammar "words"
@root line
SPACE := [ \t]+
WORD  := ALPHA+
line  := WORD+
"two words"  → ok
"two\nlines" → 1:4: no token matches here

Steht @skip SPACE über der Neudeklaration, wird die Grammatik stattdessen abgelehnt:

@grammar "words"
@root line
@skip SPACE
SPACE := [ \t]+
4:1: cannot override SPACE: already used at line 3, column 7