A linguagem EVE

A EVE é o motor de correspondência de padrões por trás do filtro de chat do Verité. Vem com a sua própria pequena linguagem para criar ficheiros de filtro. Esta página é o guia de topo: o que é a EVE, como um ficheiro de filtro está estruturado e as diretivas que compõem um documento. Cada um dos dois dialetos tem a sua própria página:

  • O ExpandaEVE é a forma explícita que se escreve à mão. Utiliza palavras como HEAR, SUFFIX, NEVER e PLURAL.
  • O CompactaEVE é a forma compilada e concisa e a semântica do correspondente por baixo dela. Cada construção do ExpandaEVE é reduzida a um símbolo do CompactaEVE antes de correr.

O que é a EVE

A EVE lê um documento de filtro e produz um conjunto de regras compiladas. Cada regra é um padrão que decide se uma palavra candidata (ou, para alguns tipos de regra, uma mensagem inteira) é uma correspondência. O motor é deliberadamente tolerante à evasão: uma regra difusa corresponde através de trocas de vogais, lacunas inseridas, letras esticadas e truques semelhantes, por isso uma única raiz criada apanha muitas grafias sem que o autor liste cada uma.

Um ficheiro de filtro é texto UTF-8 simples. As linhas que estão em branco ou começam por # são ignoradas, por isso # inicia um comentário de linha inteira.

As duas formas e como se relacionam

Cria em ExpandaEVE. Quando um documento é carregado, cada instrução é traduzida para CompactaEVE, e o CompactaEVE é compilado no correspondente executável. O fluxo é:

ExpandaEVE source  ->  CompactaEVE source  ->  compiled rules
     (authoring)          (terse form)          (the matcher)

A tradução é puramente uma reescrita. Tudo o que pode expressar em ExpandaEVE torna-se CompactaEVE real, e cada decisão de correspondência é tomada pela forma compilada. Um documento também pode ser escrito diretamente em CompactaEVE: os verbos das instruções são as mesmas palavras em minúsculas (hear, match, let, define, realm, e assim por diante), e uma instrução que não utilize nenhuma construção exclusiva do ExpandaEVE passa pelo tradutor quase textualmente.

Que forma devo ler?

Se está a escrever ou a ler ficheiros .eve, comece pelo ExpandaEVE. Leia o CompactaEVE quando quiser compreender exatamente como um padrão corresponde, ou quando estiver a ler a saída compilada.

Estrutura do documento

Um documento é uma sequência de instruções, uma por linha lógica. As palavras-chave de instrução reconhecidas são DEFINE, LET, REALM, HEAR, FIND, MATCH, ANYWHERE e SEQUENCE, mais a linha de cabeçalho eve:. Qualquer linha que não esteja em branco, não seja um comentário e não comece por uma palavra-chave reconhecida levanta um erro em vez de ser ignorada.

O cabeçalho eve:

Uma primeira linha opcional declara a versão e o idioma:

eve: 1.0 English

O texto após eve: até ao primeiro espaço é a versão. O restante é o nome do idioma. Ambos são registados no programa compilado. Um cabeçalho apenas com uma versão e sem idioma é aceite.

DEFINE: declarar ids de flags

DEFINE regista um nome de flag e o id para o qual mapeia. Cada flag que uma regra define com FLAG(...) tem de ser declarada, ou o documento não carrega.

DEFINE sh AS selfharm
DEFINE ea AS abuse
DEFINE pf AS profanity

O nome à esquerda é o que as regras referenciam. O id à direita é a categoria que o filtro reporta. Consulte Flags para saber como as regras as utilizam.

LET: definir uma função (classe nomeada)

LET function(name) BE ... declara uma classe nomeada: uma lista de palavras ou fragmentos intercambiáveis que uma regra pode invocar pelo nome. No CompactaEVE a mesma classe escreve-se let &name be ....

LET function(genderword) BE female OR girl OR woman OR male OR guy OR guys OR men OR man

Os membros são separados por OR. Uma vez declarada, uma classe é referenciada noutro lugar com function(name) no ExpandaEVE ou &name no CompactaEVE. Uma referência de classe expande-se para todos os seus membros. As classes podem carregar um marcador (WHOLE) ou (ROOT) predefinido no nome, que é herdado pelas referências a menos que a referência o substitua:

LET function(frenchstuff) (WHOLE) BE franger OR frenchie OR jizzbag

Consulte Funções e classes para a referência completa, incluindo como uma classe é utilizada como raiz, como grupo, como alias e dentro de um esqueleto.

Classes numeradas e vogais

Uma classe cujo nome é feito inteiramente de dígitos contribui com os seus membros de um único carácter para o conjunto de vogais incorporado que a correspondência relaxada utiliza. É assim que o alfabeto de vogais para a tolerância a leetspeak é montado. Consulte Esqueletos e a lista de classes de caracteres.

REALM: agrupar regras

REALM define o realm a que todas as regras seguintes pertencem, até ao próximo REALM. Um realm é um rótulo utilizado para organizar e delimitar regras. Não altera a forma como uma regra corresponde.

REALM racial_and_ethnic_slurs

Cada regra HEAR, FIND, MATCH, ANYWHERE e SEQUENCE que se segue carrega esse nome de realm até que declare um realm diferente.

As instruções de regra

Cinco instruções declaram regras. Cada uma escreve-se como o verbo, um nome, a palavra-chave AS e um corpo. O nome e o corpo podem abranger várias linhas: o corpo corre até à próxima palavra-chave de instrução no início de uma linha.

Instrução Tipo de regra Corresponde a
HEAR name AS ... Difusa Uma única palavra, tolerante à evasão. Este é o caso comum.
FIND name AS ... Difusa Idêntica a HEAR. Uma grafia alternativa do mesmo verbo.
MATCH name AS ... Estrita Toda a entrada, com classes exatas e capturas. Consulte Regras estritas.
ANYWHERE name AS ... Anywhere Dispara quando cada grupo listado aparece algures na mensagem.
SEQUENCE name AS ... Sequence Uma sequência ordenada de glifos que aparecem por ordem ao longo da mensagem.

HEAR e FIND são o mesmo tipo de regra, por isso este guia utiliza HEAR em todo o texto. O corpo de uma regra difusa é um padrão ExpandaEVE completo: uma raiz mais qualquer uma das construções na página do ExpandaEVE.

ANYWHERE e SEQUENCE

ANYWHERE constrói uma regra de coocorrência: o corpo é uma lista de grupos separados por WITH, e a regra dispara apenas quando pelo menos um membro de cada grupo é encontrado algures na mensagem. Cada membro é compilado como o seu próprio correspondente difuso de palavra inteira, por isso os membros continuam a tolerar a evasão. Uma regra ANYWHERE precisa de pelo menos dois grupos.

SEQUENCE é utilizada para padrões ordenados de símbolos e emoji e está documentada com o quadro de símbolos, que é abordado separadamente. Dispara quando todos os seus passos de glifos aparecem por ordem ao longo da mensagem, e um prefixo mirror também aceita a ordem inversa. Uma regra SEQUENCE precisa de pelo menos dois glifos.

Um ficheiro mínimo completo

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)

Isto declara uma flag, abre um realm e adiciona uma regra difusa. A regra corresponde à palavra inteira shit com qualquer uma das terminações listadas, recusa as palavras inocentes listadas e reporta a categoria profanity. Leia a referência do ExpandaEVE para cada construção utilizada aqui.