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: