|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/Gram1.lua.html
-- http://anggtwu.net/LUA/Gram1.lua
-- (find-angg "LUA/Gram1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- (defun e () (interactive) (find-angg "LUA/Gram1.lua"))
-- (defun d () (interactive) (find-luademo-links "LUA/Gram1.lua" "Gram-tests"))
-- (find-es "lpeg" "lpeg-quickref")
-- (find-es "lua5" "metatable-reductions")
-- (find-angg "LUA/eoo.lua")
-- «.without-Gram» (to "without-Gram")
-- «.Gram» (to "Gram")
-- «.Gram-tests» (to "Gram-tests")
require "lpeg" -- (find-es "lpeg" "lpeg-quickref")
-- (find-es "lpeg" "globals")
B,C,P,R,S,V = lpeg.B,lpeg.C,lpeg.P,lpeg.R,lpeg.S,lpeg.V
Cb,Cc,Cf,Cg = lpeg.Cb,lpeg.Cc,lpeg.Cf,lpeg.Cg
Cp,Cs,Ct = lpeg.Cp,lpeg.Cs,lpeg.Ct
Carg,Cmt = lpeg.Carg,lpeg.Cmt
-- __ ___ _ _ _ ____
-- \ \ / (_) |_| |__ ___ _ _| |_ / ___|_ __ __ _ _ __ ___
-- \ \ /\ / /| | __| '_ \ / _ \| | | | __| | | _| '__/ _` | '_ ` _ \
-- \ V V / | | |_| | | | (_) | |_| | |_ | |_| | | | (_| | | | | | |
-- \_/\_/ |_|\__|_| |_|\___/ \__,_|\__| \____|_| \__,_|_| |_| |_|
--
-- «without-Gram» (to ".without-Gram")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Gram1.lua"
gram = {
Num = (R"09")^1,
S = (S" \t\n")^0,
Nums = (V"S" * V"Num")^1,
}
gram[1] = "Num"
= P(gram):match("987 654 321")
gram.Num = Cs(R"09"^1)
= P(gram):match("987 654 321")
gram[1] = "Nums"
= P(gram):match("987 654 321")
--]]
-- ____
-- / ___|_ __ __ _ _ __ ___
-- | | _| '__/ _` | '_ ` _ \
-- | |_| | | | (_| | | | | | |
-- \____|_| \__,_|_| |_| |_|
--
-- In the terminology of
-- http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html#grammar
-- an object of the class Gram is a grammar that:
-- 1) hasn't been "fixed" yet,
-- 2) doesn't have an initial rule yet,
-- 3) has a nicer interface.
--
-- The typical usage is:
-- gr,V = Gram.new()
-- This "V" can be used both as an lvalue and as a synonym for lpeg.V.
-- For example, these two lines
-- V.foo = V.bar
-- V.plic = V"ploc"
-- are equivalent to:
-- gr.entries["foo"] = lpeg.V("bar")
-- gr.entries["plic"] = lpeg.V("ploc")
-- Actually the lvalues here are V.foo and V.bar, not V itself.
--
-- «Gram» (to ".Gram")
Gram = Class {
type = "Gram",
new = function ()
return Gram.fromentries(VTable {})
end,
fromentries = function (entries)
return Gram {entries=entries},
Gram.buildV (entries)
end,
buildV = function (entries)
local V = {}
local mt = {}
setmetatable(V, mt)
mt.__call = function (v,key) return lpeg.V(key) end
mt.__index = function (v,key) return lpeg.V(key) end
mt.__newindex = function (v,key,val) entries[key] = val end
return V
end,
--
from = function (oldgram)
return Gram.fromentries(VTable(copy(oldgram.entries)))
end,
--
__tostring = function (gr) return gr:tostring() end,
__index = {
compile = function (gr, top)
local entries = copy(gr.entries)
entries[1] = top
return lpeg.P(entries)
end,
cm = function (gr, top, subj, pos)
if type(pos) == "string" then pos = subj:match(pos) end
return gr:compile(top):match(subj, pos)
end,
cmp = function (gr, top, subj, pos)
return PP(gr:cm(top, subj, pos))
end,
tostring = function (gr, sep)
local ks = sorted(keys(gr.entries))
return mapconcat(mytostring, ks, sep or "\n")
end,
},
}
-- «Gram-tests» (to ".Gram-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Gram1.lua"
gr,V = Gram.new()
V.Num = (R"09")^1
V.S = (S" \t\n")^0
V.sNum = Cs(V"Num")
= gr.entries
= gr
= gr:tostring("\n")
= gr:compile("sNum")
= gr:compile("sNum"):match("1234abc")
= gr:compile("sNum"):match("1234abc", 2)
= gr:cmp("sNum", "1234abc", 2)
gr:cmp("sNum", "1234abc", 2)
gr:cmp("sNum", "1234abc", "()3")
gr:cmp("sNum", "1234abc")
gr:cmp("sNum", "abc")
s = V"S"
V.Sum = V"Num" * s * "+" * s * V"Num"
V.sSum = Cs(V"Sum")
gr:cmp("Sum", "1 + 2 + 3 + 4 abc")
gr:cmp("sSum", "1 + 2 + 3 + 4 abc")
V.Sum = V"Num" * (s * "+" * s * V"Num")^0
gr:cmp("sSum", "1 + 2 + 3 + 4 abc")
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: