# Die EVE-Sprache

EVE ist die Mustererkennungs-Engine hinter dem Verité-Chatfilter. Sie wird mit einer eigenen kleinen Sprache zum Verfassen von Filterdateien ausgeliefert. Diese Seite ist die übergeordnete Anleitung: was EVE ist, wie eine Filterdatei strukturiert ist und welche Direktiven ein Dokument ausmachen. Die beiden Dialekte haben jeweils ihre eigene Seite:

- [ExpandaEVE](page:eve/expanda) ist die ausgeschriebene Form, die du von Hand schreibst. Sie verwendet Wörter wie `HEAR`, `SUFFIX`, `NEVER` und `PLURAL`.
- [CompactaEVE](page:eve/compacta) ist die knappe kompilierte Form und die Matcher-Semantik darunter. Jedes ExpandaEVE-Konstrukt wird vor der Ausführung auf ein CompactaEVE-Symbol heruntergebrochen.

## Was EVE ist

EVE liest ein Filterdokument und erzeugt einen Satz kompilierter Regeln. Jede Regel ist ein Muster, das entscheidet, ob ein Kandidatenwort (oder, bei einigen Regelarten, eine ganze Nachricht) ein Treffer ist. Die Engine ist bewusst tolerant gegenüber Umgehung: eine Fuzzy-Regel trifft durch Vokaltausch, eingefügte Lücken, gedehnte Buchstaben und ähnliche Tricks hindurch, sodass eine einzige verfasste Wurzel viele Schreibweisen erfasst, ohne dass der Autor jede einzeln aufführt.

Eine Filterdatei ist reiner UTF-8-Text. Zeilen, die leer sind oder mit `#` beginnen, werden ignoriert, `#` startet also einen ganzzeiligen Kommentar.

## Die zwei Formen und wie sie zusammenhängen

Du verfasst in ExpandaEVE. Wenn ein Dokument geladen wird, wird jede Anweisung in CompactaEVE übersetzt, und das CompactaEVE wird in den lauffähigen Matcher kompiliert. Der Ablauf ist:

```text
ExpandaEVE source  ->  CompactaEVE source  ->  compiled rules
     (authoring)          (terse form)          (the matcher)
```

Die Übersetzung ist rein ein Umschreiben. Alles, was du in ExpandaEVE ausdrücken kannst, wird zu echtem CompactaEVE, und jede Trefferentscheidung wird von der kompilierten Form getroffen. Ein Dokument kann auch direkt in CompactaEVE geschrieben werden: die Anweisungsverben sind dieselben Wörter in Kleinbuchstaben (`hear`, `match`, `let`, `define`, `realm` und so weiter), und eine Anweisung, die kein reines ExpandaEVE-Konstrukt verwendet, geht nahezu wörtlich durch den Übersetzer.

!!! note "Welche Form sollte ich lesen?"
    Wenn du `.eve`-Dateien schreibst oder liest, beginne mit [ExpandaEVE](page:eve/expanda). Lies [CompactaEVE](page:eve/compacta), wenn du genau verstehen willst, wie ein Muster trifft, oder wenn du die kompilierte Ausgabe liest.

## Dokumentstruktur

Ein Dokument ist eine Folge von Anweisungen, eine pro logischer Zeile. Die erkannten Anweisungsschlüsselwörter sind `DEFINE`, `LET`, `REALM`, `HEAR`, `FIND`, `MATCH`, `ANYWHERE` und `SEQUENCE`, dazu die `eve:`-Headerzeile. Jede Zeile, die nicht leer, kein Kommentar ist und nicht mit einem erkannten Schlüsselwort beginnt, löst einen Fehler aus, statt übersprungen zu werden.

### Der eve:-Header

Eine optionale erste Zeile deklariert die Version und die Sprache:

```text
eve: 1.0 English
```

Der Text nach `eve:` bis zum ersten Leerzeichen ist die Version. Der Rest ist der Sprachname. Beide werden im kompilierten Programm aufgezeichnet. Ein Header mit nur einer Version und ohne Sprache wird akzeptiert.

### DEFINE: Flag-IDs deklarieren

`DEFINE` registriert einen Flag-Namen und die ID, auf die er abbildet. Jedes Flag, das eine Regel mit `FLAG(...)` setzt, muss deklariert sein, sonst schlägt das Laden des Dokuments fehl.

```text
DEFINE sh AS selfharm
DEFINE ea AS abuse
DEFINE pf AS profanity
```

Der Name auf der linken Seite ist das, worauf Regeln verweisen. Die ID auf der rechten Seite ist die Kategorie, die der Filter meldet. Siehe [Flags](page:eve/expanda#flag-conditional-rules-and-category-tagging) dafür, wie Regeln sie verwenden.

### LET: eine Funktion definieren (benannte Klasse)

`LET function(name) BE ...` deklariert eine benannte Klasse: eine Liste austauschbarer Wörter oder Fragmente, die eine Regel per Name einbeziehen kann. In CompactaEVE wird dieselbe Klasse `let &name be ...` geschrieben.

```text
LET function(genderword) BE female OR girl OR woman OR male OR guy OR guys OR men OR man
```

Mitglieder werden durch `OR` getrennt. Einmal deklariert, wird eine Klasse anderswo mit `function(name)` in ExpandaEVE oder `&name` in CompactaEVE referenziert. Eine Klassenreferenz expandiert zu allen ihren Mitgliedern. Klassen können auf dem Namen einen Standardmarker `(WHOLE)` oder `(ROOT)` tragen, der von Referenzen geerbt wird, sofern die Referenz ihn nicht überschreibt:

```text
LET function(frenchstuff) (WHOLE) BE franger OR frenchie OR jizzbag
```

Siehe [Funktionen und Klassen](page:eve/expanda#function-named-classes) für die vollständige Referenz, einschließlich wie eine Klasse als Wurzel, als Gruppe, als Alias und innerhalb eines Skeletts verwendet wird.

!!! note "Nummerierte Klassen und Vokale"
    Eine Klasse, deren Name vollständig aus Ziffern besteht, trägt ihre Einzelzeichen-Mitglieder zum eingebauten Vokalsatz bei, den das gelockerte Matching verwendet. So wird das Vokalalphabet für die Leetspeak-Toleranz zusammengesetzt. Siehe [Skelette](page:eve/expanda#skeleton-exact-spellings) und die [Zeichenklassenliste](page:eve/expanda#inline-choice-lists).

### REALM: Regeln gruppieren

`REALM` setzt das Realm, zu dem jede folgende Regel gehört, bis zum nächsten `REALM`. Ein Realm ist ein Label, das zum Organisieren und Zuordnen von Regeln verwendet wird. Es ändert nicht, wie eine Regel trifft.

```text
REALM racial_and_ethnic_slurs
```

Jede `HEAR`-, `FIND`-, `MATCH`-, `ANYWHERE`- und `SEQUENCE`-Regel, die folgt, trägt diesen Realm-Namen, bis du ein anderes Realm deklarierst.

### Die Regelanweisungen

Fünf Anweisungen deklarieren Regeln. Jede wird als das Verb, ein Name, das Schlüsselwort `AS` und ein Rumpf geschrieben. Der Name und der Rumpf können sich über mehrere Zeilen erstrecken: der Rumpf läuft bis zum nächsten Anweisungsschlüsselwort am Anfang einer Zeile.

| Anweisung | Regelart | Trifft |
|-----------|-----------|---------|
| `HEAR name AS ...` | Fuzzy | Ein einzelnes Wort, tolerant gegenüber Umgehung. Dies ist der häufige Fall. |
| `FIND name AS ...` | Fuzzy | Identisch mit `HEAR`. Eine alternative Schreibweise desselben Verbs. |
| `MATCH name AS ...` | Strikt | Die gesamte Eingabe, mit exakten Klassen und Erfassungen. Siehe [Strikte Regeln](page:eve/compacta#strict-rules-match). |
| `ANYWHERE name AS ...` | Anywhere | Feuert, wenn jede aufgeführte Gruppe irgendwo in der Nachricht erscheint. |
| `SEQUENCE name AS ...` | Sequence | Eine geordnete Folge von Glyphen, die der Reihe nach über die Nachricht hinweg erscheint. |

`HEAR` und `FIND` sind dieselbe Regelart, diese Anleitung verwendet also durchgehend `HEAR`. Ein Fuzzy-Regelrumpf ist ein vollständiges ExpandaEVE-Muster: eine Wurzel plus beliebige der Konstrukte auf der [ExpandaEVE-Seite](page:eve/expanda).

!!! note "ANYWHERE und SEQUENCE"
    `ANYWHERE` baut eine Ko-Vorkommens-Regel: der Rumpf ist eine Liste von Gruppen, getrennt durch `WITH`, und die Regel feuert nur, wenn mindestens ein Mitglied jeder Gruppe irgendwo in der Nachricht gefunden wird. Jedes Mitglied wird als eigener ganzwortiger Fuzzy-Matcher kompiliert, Mitglieder tolerieren also weiterhin Umgehung. Eine `ANYWHERE`-Regel braucht mindestens zwei Gruppen.

    `SEQUENCE` wird für geordnete Symbol- und Emoji-Muster verwendet und ist mit dem Symbol-Board dokumentiert, das separat behandelt wird. Sie feuert, wenn ihre Glyphenschritte alle der Reihe nach über die Nachricht hinweg erscheinen, und ein `mirror`-Präfix akzeptiert auch die umgekehrte Reihenfolge. Eine `SEQUENCE`-Regel braucht mindestens zwei Glyphen.

## Eine vollständige minimale Datei

```text
eve: 1.0 English

DEFINE pf AS profanity

REALM profanity

HEAR rule
AS
  shit(WHOLE)
  suffix(NONE OR s OR ty OR head OR heads)
  NEVER(shitake OR shiitake OR mishit)
  FLAG(pf YES)
```

Dies deklariert ein Flag, öffnet ein Realm und fügt eine Fuzzy-Regel hinzu. Die Regel trifft das ganze Wort `shit` mit einer der aufgeführten Endungen, verweigert die aufgeführten unschuldigen Wörter und meldet die Kategorie `profanity`. Lies die [ExpandaEVE-Referenz](page:eve/expanda) für jedes hier verwendete Konstrukt.
