LUA > LPeg > Saját számológép

Azt hiszem mindenki álmodott saját számológépről. Ez a fajta igencsak érdekes, mert egy mintaillesztő nyelvet használ a célra. Mindehhez fel kell rakni az lpeg-t, ami az én csomagkezelőmben (synaptic) az "lpeg" keresőszó alapján megtalálható.

Mivel több vagy kevesebb az LPeg a reguláris kifejezéseknél? LPeg-ben a minták elsőosztályú változók, úgy mint a függvények.

Hogyan is kéne értelmezni a kódot?
(1) Létrehozzuk a lexikai elemeket: Whitespace karakterek, Számok, Nyitó/Csukó zárójel, Szorzás/Osztás operátor, Összeadás/Kivonás operátor.
(2) Írunk egy függvényt, ami megkapja a két operandust és a közrezárt operátort. Az operátor alapján dönti el milyen műveletet végez az operandusokon, az eredményt visszaadja
(3) A bonyolult rész. Nyelvtan definiálása. A tábla első bejegyzése az a nem-terminális elem, amit meghív az adott mintára. Ezután a kulcsok változók amiknek az értékei LPeg minták.

Fontos hangsúlyozni, hogy a mintaillesztés "anchored", ami számomra azt jelenti, hogy az illesztést rögtön az első karakternél kezdi.

Vajon hol kell módosítani ahhoz, hogy támogassa a racionális számokat?

local Number = lpeg.C(lpeg.P"-"^-1 * lpeg.R("09")^1 * lpeg.P"."^-1 * lpeg.R("09")^0) * Space

 


lpeg = require "lpeg"

if arg[1] == nil then
	
	print ""
	print "Lpeg calc v0.2 --- LUA calculator"
	print "================================"
	print "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html"
	print ""
	print "Usage: lua calc.lua <expression>"
	print "Example: lua calc.lua (2+2)*10+2"
	print ""
	print ""
	os.exit(1)
end

-- Lexical Elements
local Space = lpeg.S(" \n\t")^0
local Number = lpeg.C(lpeg.P"-"^-1 * lpeg.R("09")^1) * Space
local FactorOp = lpeg.C(lpeg.S("+-")) * Space
local TermOp = lpeg.C(lpeg.S("*/")) * Space
local Open = "(" * Space
local Close = ")" * Space


-- Auxiliary function
function eval (v1, op, v2)
  if (op == "+") then return v1 + v2
  elseif (op == "-") then return v1 - v2
  elseif (op == "*") then return v1 * v2
  elseif (op == "/") then return v1 / v2
  end
end

-- Grammar
local V = lpeg.V
G = lpeg.P{ "Exp",
  Exp = lpeg.Cf(V"Factor" * lpeg.Cg(FactorOp * V"Factor")^0, eval);
  Factor = lpeg.Cf(V"Term" * lpeg.Cg(TermOp * V"Term")^0, eval);
  Term = Number / tonumber + Open * V"Exp" * Close;
}

-- small example
print(lpeg.match(G, arg[1] ))  

Hozzászólások