0Pricing
Lua Academy · Lezione

Semplice parser di espressioni

Costruisca un parser ricorsivo a discesa per espressioni aritmetiche in Lua puro.

Semplice parser di espressioni è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Obiettivo: analizzare espressioni aritmetiche

Crei un parser a discesa ricorsiva in puro Lua che analizzi e valuti espressioni come 3 + 4 * (2 - 1), rispettando la precedenza degli operatori.

Tokenizer

Per prima cosa, trasformi l'input in token: numeri, operatori e parentesi.

local function tokenize(expr)
  local tokens = {}
  for tok in expr:gmatch("[%d%.]+|[%+%-%*/%(%)%^]|%S") do
    tokens[#tokens+1] = tok
  end
  return tokens
end

Tokenizer migliorato

Un tokenizer più robusto che utilizza pattern gmatch.

local function tokenize(expr)
  local tokens = {}
  for tok in expr:gmatch("%d+%.?%d*|[%+%-%*/%(%)%^]") do
    tokens[#tokens+1] = tok
  end
  return tokens
end

Stato del parser

Il parser conserva un elenco di token e una posizione. Le funzioni di supporto peek e consume avanzano tra i token.

local function newParser(tokens)
  local pos = 1
  local function peek() return tokens[pos] end
  local function consume() pos = pos + 1; return tokens[pos-1] end
  return {peek=peek, consume=consume}
end

Grammatica delle espressioni

La grammatica rispetta la precedenza:

  • expr = term ((+ | -) term)*
  • term = factor ((* | /) factor)*
  • factor = number | (expr) | -factor

Analisi dei termini

Analizzi le espressioni additive analizzando i termini e combinando le operazioni +/- da sinistra a destra.

local parseExpr, parseTerm, parseFactor
parseExpr = function(p)
  local val = parseTerm(p)
  while p.peek() == "+" or p.peek() == "-" do
    local op = p.consume()
    local right = parseTerm(p)
    if op == "+" then val = val + right
    else val = val - right end
  end
  return val
end

Analisi dei fattori

Analizzi le espressioni moltiplicative, inclusa l'elevazione a potenza.

parseTerm = function(p)
  local val = parseFactor(p)
  while p.peek() == "*" or p.peek() == "/" do
    local op = p.consume()
    local right = parseFactor(p)
    if op == "*" then val = val * right
    else val = val / right end
  end
  return val
end

Analisi di numeri e parentesi

Analizzi gli atomi: literal, sottoespressioni tra parentesi e negazione unaria.

parseFactor = function(p)
  local tok = p.peek()
  if tok == "(" then
    p.consume()  -- (
    local val = parseExpr(p)
    p.consume()  -- )
    return val
  elseif tok == "-" then
    p.consume()
    return -parseFactor(p)
  else
    return tonumber(p.consume())
  end
end

Mettere tutto insieme

Trasformi in token, analizzi e valuti un'espressione.

local function eval(expr)
  local tokens = tokenize(expr)
  local parser = newParser(tokens)
  return parseExpr(parser)
end
print(eval("3 + 4 * 2"))      -- 11
print(eval("(3 + 4) * 2"))    -- 14
print(eval("2 ^ 10"))         -- 1024 (if ^ is supported)

Estendere il parser

Aggiunga variabili, funzioni, operatori di confronto e literal stringa estendendo la grammatica e aggiungendo nuovi casi a parseFactor.

Segnalazione degli errori

Tenga traccia della riga e della colonna nel tokenizer. Generi messaggi di errore significativi: "Expected ')' at position 7, got '+'".

Generatori di parser

Per grammatiche complesse, utilizzi generatori di parser come LPEG (Parsing Expression Grammars). LPEG è molto più potente ed espressivo di un parser a discesa ricorsiva scritto manualmente per le grammatiche di grandi dimensioni.

Domanda sui parser

Che cosa utilizza un parser a discesa ricorsiva per imporre la precedenza degli operatori?

Riepilogo: parser di espressioni semplice

Un parser a discesa ricorsiva utilizza una funzione per ogni regola della grammatica, imponendo naturalmente la precedenza degli operatori attraverso la gerarchia delle chiamate. Esegua prima la tokenizzazione, quindi implementi le funzioni expr → term → factor. Lo estenda con variabili e funzioni per ottenere un linguaggio completo per le espressioni.

Domande Frequenti

La lezione «Semplice parser di espressioni» è gratuita?

Sì — il testo completo di «Semplice parser di espressioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Semplice parser di espressioni»?

Costruisca un parser ricorsivo a discesa per espressioni aritmetiche in Lua puro. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Semplice parser di espressioni»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Principi di progettazione delle DSL in Lua
  2. Overloading degli operatori per una DSL fluida
  3. Creazione di una DSL di configurazione
  4. Semplice parser di espressioni
← Torna a Lua Academy