Ce este
Șablonul Interpreter evaluează propoziții dintr-un limbaj mic construind un arbore de noduri de expresie — numere, adunări, scăderi — și apoi parcurgând acel arbore. Un număr se evaluează la el însuși; o adunare își evaluează cele două părți și le adună.
În TypeScript arborele este o uniune discriminată: fiecare nod este un obiect simplu cu un câmp kind, iar o singură funcție face switch pe acel câmp. Deoarece uniunea enumeră fiecare tip de nod, compilatorul se plânge dacă lipsește un caz.
Se potrivește limbajelor mici: filtre, formule, reguli simple. Limbajele reale merită unelte reale de parsare.
Exemplu: un calculator minuscul
Intrarea 3 + 4 - 2 devine un arbore de noduri number, add și subtract. Un singur apel la interpret() pe rădăcină evaluează întreaga expresie.
Un arbore, o funcție interpret
parse construiește arborele de la stânga la dreapta; interpret îl parcurge și afișează 3 + 4 - 2 = 5. Suportul pentru * ar însemna un nou membru al uniunii plus un nou case — cele existente rămân neatinse.
Ieșire: program TypeScript și rezultatul capturat
// Fiecare nod este un obiect simplu etichetat cu un câmp kind.
type Expression =
| { kind: "number"; value: number }
| { kind: "add"; left: Expression; right: Expression }
| { kind: "subtract"; left: Expression; right: Expression }
function interpret(expr: Expression): number {
switch (expr.kind) {
case "number":
return expr.value
case "add":
return interpret(expr.left) + interpret(expr.right)
case "subtract":
return interpret(expr.left) - interpret(expr.right)
}
}
function parse(input: string): Expression {
const parts = input.split(" ")
let expr: Expression = { kind: "number", value: Number(parts[0]) }
for (let i = 1; i < parts.length; i += 2) {
const right: Expression = { kind: "number", value: Number(parts[i + 1]) }
expr = parts[i] === "+"
? { kind: "add", left: expr, right }
: { kind: "subtract", left: expr, right }
}
return expr
}
const input = "3 + 4 - 2"
console.log(input, "=", interpret(parse(input)))
Când să îl folosești
Folosește-l când utilizatorii sau configurațiile exprimă logică într-un limbaj mic conceput de tine: filtre de căutare, formule de preț, reguli de validare.
Evită-l când „limbajul” înseamnă trei opțiuni fixe (un simplu switch este de ajuns) — sau când este un limbaj real (folosește un generator de parsere ori un motor existent).
Avantaje și dezavantaje
Avantaje: gramatica se pune în corespondență unu-la-unu cu membrii uniunii; operațiile noi sunt membri noi; arborii de expresii pot fi construiți, verificați și reutilizați.
Dezavantaje: devine dificil pe măsură ce gramatica crește; parsarea tot trebuie scrisă; performanța este modestă față de logica compilată.