# Il linguaggio EVE

EVE è il motore di pattern matching dietro il filtro chat di Verité. Viene distribuito con il suo piccolo linguaggio per la scrittura dei file di filtro. Questa pagina è la guida di livello superiore: cos'è EVE, come è strutturato un file di filtro e le direttive che compongono un documento. I due dialetti hanno ciascuno la propria pagina:

- [ExpandaEVE](page:eve/expanda) è la forma esplicita che scrivi a mano. Usa parole come `HEAR`, `SUFFIX`, `NEVER` e `PLURAL`.
- [CompactaEVE](page:eve/compacta) è la forma compilata concisa e la semantica del matcher sottostante. Ogni costrutto ExpandaEVE viene ridotto a un simbolo CompactaEVE prima di essere eseguito.

## Cos'è EVE

EVE legge un documento di filtro e produce un insieme di regole compilate. Ogni regola è un pattern che decide se una parola candidata (o, per alcuni tipi di regola, un intero messaggio) è una corrispondenza. Il motore è deliberatamente tollerante verso l'evasione: una regola fuzzy corrisponde attraverso scambi di vocali, spazi inseriti, lettere allungate e trucchi simili, così che una singola radice scritta catturi molte grafie senza che l'autore le elenchi una per una.

Un file di filtro è testo semplice UTF-8. Le righe vuote o che iniziano con `#` vengono ignorate, quindi `#` avvia un commento su tutta la riga.

## Le due forme e come si relazionano

Scrivi in ExpandaEVE. Quando un documento viene caricato, ogni istruzione viene tradotta in CompactaEVE, e il CompactaEVE viene compilato nel matcher eseguibile. Il flusso è:

```text
ExpandaEVE source  ->  CompactaEVE source  ->  compiled rules
     (authoring)          (terse form)          (the matcher)
```

La traduzione è puramente una riscrittura. Tutto ciò che puoi esprimere in ExpandaEVE diventa vero CompactaEVE, e ogni decisione di corrispondenza è presa dalla forma compilata. Un documento può anche essere scritto direttamente in CompactaEVE: i verbi delle istruzioni sono le stesse parole in minuscolo (`hear`, `match`, `let`, `define`, `realm` e così via), e un'istruzione che non usa alcun costrutto esclusivo di ExpandaEVE passa attraverso il traduttore quasi letteralmente.

!!! note "Quale forma dovrei leggere?"
    Se stai scrivendo o leggendo file `.eve`, inizia con [ExpandaEVE](page:eve/expanda). Leggi [CompactaEVE](page:eve/compacta) quando vuoi capire esattamente come un pattern corrisponde, o quando stai leggendo l'output compilato.

## Struttura del documento

Un documento è una sequenza di istruzioni, una per riga logica. Le parole chiave di istruzione riconosciute sono `DEFINE`, `LET`, `REALM`, `HEAR`, `FIND`, `MATCH`, `ANYWHERE` e `SEQUENCE`, più la riga di intestazione `eve:`. Qualsiasi riga che non sia vuota, non sia un commento e non inizi con una parola chiave riconosciuta genera un errore anziché essere saltata.

### L'intestazione eve:

Una prima riga opzionale dichiara la versione e la lingua:

```text
eve: 1.0 English
```

Il testo dopo `eve:` fino al primo spazio è la versione. Il resto è il nome della lingua. Entrambi sono registrati sul programma compilato. Un'intestazione con solo una versione e nessuna lingua è accettata.

### DEFINE: dichiarare gli id dei flag

`DEFINE` registra un nome di flag e l'id a cui si mappa. Ogni flag che una regola imposta con `FLAG(...)` deve essere dichiarato, altrimenti il documento non riesce a caricarsi.

```text
DEFINE sh AS selfharm
DEFINE ea AS abuse
DEFINE pf AS profanity
```

Il nome a sinistra è ciò a cui le regole fanno riferimento. L'id a destra è la categoria che il filtro riporta. Vedi [Flag](page:eve/expanda#flag-conditional-rules-and-category-tagging) per come le regole li usano.

### LET: definire una funzione (classe con nome)

`LET function(name) BE ...` dichiara una classe con nome: un elenco di parole o frammenti intercambiabili che una regola può richiamare per nome. In CompactaEVE la stessa classe si scrive `let &name be ...`.

```text
LET function(genderword) BE female OR girl OR woman OR male OR guy OR guys OR men OR man
```

I membri sono separati da `OR`. Una volta dichiarata, una classe viene referenziata altrove con `function(name)` in ExpandaEVE o `&name` in CompactaEVE. Un riferimento a una classe si espande in tutti i suoi membri. Le classi possono portare un marcatore predefinito `(WHOLE)` o `(ROOT)` sul nome, che viene ereditato dai riferimenti a meno che il riferimento non lo sovrascriva:

```text
LET function(frenchstuff) (WHOLE) BE franger OR frenchie OR jizzbag
```

Vedi [Funzioni e classi](page:eve/expanda#function-named-classes) per il riferimento completo, incluso come una classe viene usata come radice, come gruppo, come alias e all'interno di uno skeleton.

!!! note "Classi numerate e vocali"
    Una classe il cui nome è composto interamente da cifre contribuisce con i suoi membri a carattere singolo all'insieme di vocali integrato che il matching rilassato usa. È così che viene assemblato l'alfabeto di vocali per la tolleranza al leetspeak. Vedi [Skeleton](page:eve/expanda#skeleton-exact-spellings) e la [lista delle classi di caratteri](page:eve/expanda#inline-choice-lists).

### REALM: raggruppare le regole

`REALM` imposta il realm a cui appartiene ogni regola seguente, fino al successivo `REALM`. Un realm è un'etichetta usata per organizzare e delimitare le regole. Non cambia il modo in cui una regola corrisponde.

```text
REALM racial_and_ethnic_slurs
```

Ogni regola `HEAR`, `FIND`, `MATCH`, `ANYWHERE` e `SEQUENCE` che segue porta con sé quel nome di realm finché non dichiari un realm diverso.

### Le istruzioni di regola

Cinque istruzioni dichiarano regole. Ciascuna è scritta come il verbo, un nome, la parola chiave `AS` e un corpo. Il nome e il corpo possono estendersi su più righe: il corpo prosegue fino alla successiva parola chiave di istruzione all'inizio di una riga.

| Istruzione | Tipo di regola | Corrisponde |
|-----------|-----------|---------|
| `HEAR name AS ...` | Fuzzy | Una singola parola, tollerante verso l'evasione. Questo è il caso comune. |
| `FIND name AS ...` | Fuzzy | Identica a `HEAR`. Una grafia alternativa dello stesso verbo. |
| `MATCH name AS ...` | Strict | L'intero input, con classi e catture esatte. Vedi [Regole strict](page:eve/compacta#strict-rules-match). |
| `ANYWHERE name AS ...` | Anywhere | Si attiva quando ogni gruppo elencato appare da qualche parte nel messaggio. |
| `SEQUENCE name AS ...` | Sequence | Una serie ordinata di glifi che appaiono in ordine attraverso il messaggio. |

`HEAR` e `FIND` sono lo stesso tipo di regola, quindi questa guida usa `HEAR` ovunque. Il corpo di una regola fuzzy è un pattern ExpandaEVE completo: una radice più uno qualsiasi dei costrutti nella [pagina ExpandaEVE](page:eve/expanda).

!!! note "ANYWHERE e SEQUENCE"
    `ANYWHERE` costruisce una regola di co-occorrenza: il corpo è un elenco di gruppi separati da `WITH`, e la regola si attiva solo quando almeno un membro di ogni gruppo viene trovato da qualche parte nel messaggio. Ogni membro è compilato come il proprio matcher fuzzy a parola intera, quindi i membri tollerano comunque l'evasione. Una regola `ANYWHERE` ha bisogno di almeno due gruppi.

    `SEQUENCE` viene usata per pattern ordinati di simboli ed emoji ed è documentata con il tabellone dei simboli, che è trattato separatamente. Si attiva quando i suoi passaggi di glifi appaiono tutti in ordine attraverso il messaggio, e un prefisso `mirror` accetta anche l'ordine inverso. Una regola `SEQUENCE` ha bisogno di almeno due glifi.

## Un file minimo completo

```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)
```

Questo dichiara un flag, apre un realm e aggiunge una regola fuzzy. La regola corrisponde all'intera parola `shit` con una qualsiasi delle terminazioni elencate, rifiuta le parole innocenti elencate e riporta la categoria `profanity`. Leggi il [riferimento ExpandaEVE](page:eve/expanda) per ogni costrutto usato qui.
