Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file: -- http://anggtwu.net/LUA/ParseTree2.lua.html -- http://anggtwu.net/LUA/ParseTree2.lua -- (find-angg "LUA/ParseTree2.lua") -- Author: Eduardo Ochs <eduardoochs@gmail.com> -- Version: 20240122 -- -- This file implements a way to produce figures like these ones, -- https://en.wikipedia.org/wiki/Context-free_grammar -- http://anggtwu.net/LATEX/2023-2-C2-Tudo.pdf#page=6 -- (c2m231introp 5 "gramatica-fig") -- (c2m231introa "gramatica-fig") -- using a parser written in ELpeg1, -- (find-angg "LUA/ELpeg1.lua") -- and a totexer: -- (find-angg "LUA/ToTeX1.lua") -- (find-angg "LUA/ToTeX1.lua" "totexer") -- See: -- (find-eev2023replsvideo "57:25") -- (find-eev2023replslsubs "57:25") -- (defun pt2 () (interactive) (find-angg "LUA/ParseTree2.lua")) -- (defun pt1 () (interactive) (find-angg "LUA/ParseTree1.lua")) -- Supersedes: -- (find-angg "LUA/ParseTree1.lua") -- «.b-and-e» (to "b-and-e") -- «.subj» (to "subj") -- «.grammar» (to "grammar") -- «.grammar-tests» (to "grammar-tests") -- «.fmts» (to "fmts") -- «.fmts-tests» (to "fmts-tests") -- «.ParseTree» (to "ParseTree") -- «.ParseTree-tests» (to "ParseTree-tests") require "ELpeg1" -- (find-angg "LUA/ELpeg1.lua") require "ToTeX1" -- (find-angg "LUA/ToTeX1.lua") require "Co1" -- (find-angg "LUA/Co1.lua") -- «b-and-e» (to ".b-and-e") -- (find-angg "LUA/ELpeg1.lua" "Gram") -- (find-angg "LUA/ELpeg1.lua" "Gram" "mt_VAST =") -- (find-angg "LUA/ELpeg1.lua" "Gram" "mt_VAST =" "If gr.be is true") Gram.__index.be = true -- «subj» (to ".subj") -- (find-angg "LUA/ELpeg1.lua" "Gram" "cm0 =") Gram.__index.cm0 = function (gr, top, newsubj, pos) subj = newsubj if type(pos) == "string" then pos = subj:match(pos) end return gr:compile(top):match(subj, pos) end -- «grammar» (to ".grammar") gr,V,VA,VE,PE = Gram.new() _ = S(" ")^0 VA.num = (R"09"^1):C() VA.op = (S"+-"):C() VA.sum = V.num *(_*V.op*_*V.num)^0 VA.Stmt = V.Id *_*C("=")*_* V.Expr *_*";" + "{" *_* V.StmtList *_*"}" + C("if") *_* "(" *_* V.Expr *_* ")" *_* V.Stmt VA.StmtList = V.Stmt * (_*V.Stmt)^0 V.Expr0 = V.Id + V.Num VA.Expr = V.Expr0*(_*V.Optr*_*V.Expr0)^0 VA.Id = C"x" + C"y" VA.Num = C(R"09") VA.Optr = C(S">+") -- «grammar-tests» (to ".grammar-tests") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ParseTree2.lua" o = gr:cm0("Stmt", "if (x>9) { x=0; y=y+1;}") = o = o[1] = o[2][1] PPV(o[2][1]) --]==] defs.ParseTree = [=[ % (find-LATEX "2023-2-C2-intro.tex" "gramatica-fig") \def\und#1#2{\underbrace{#1}_{\textstyle#2}} \def\ColorRed#1{{\color{red}{#1}}} \def\NT #1{\langle\textsf{#1}\rangle} % non-terminal \def\SUBJ#1{\ColorRed{\tt#1}} \def\SUBJ#1{\mathstrut\ColorRed{\tt#1}} % a substring of subj, in tt font ]=] -- «fmts» (to ".fmts") -- fmts["co"] = "{\tt<ParseTree_cot(o[1])>}" fmts["(subj)"] = "\\SUBJ{<ParseTree_cot(o[1])>}" fmts["und"] = "\\und{<1>}{<2>}" fmts["."] = "<mapconcat(totex, o)>" fmts["<>"] = "\\NT{<o[1]>}" -- «fmts-tests» (to ".fmts-tests") --[==[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ParseTree2.lua" osubj = mkast("(subj)", "{ }") ont = mkast("<>", "Stmts") o = mkast("und", osubj, ont) = o:show {em=1} * (etv) --]==] -- ____ _____ -- | _ \ __ _ _ __ ___ __|_ _| __ ___ ___ -- | |_) / _` | '__/ __|/ _ \| || '__/ _ \/ _ \ -- | __/ (_| | | \__ \ __/| || | | __/ __/ -- |_| \__,_|_| |___/\___||_||_| \___|\___| -- -- «ParseTree» (to ".ParseTree") -- TODO: Use: -- (find-angg "LUA/MapAST1.lua" "MapAST") ParseTree_co = Co.new("#${} ", "%&\\^_~"):add("\n", "\\\\\n") ParseTree_cot = ParseTree_co:translator() ParseTree = Class { type = "ParseTree", deletestrings = function (o) return ParseTree{}:copyo(o,"mkstr0") end, dotstrings = function (o) return ParseTree{}:copyo(o,"mkstr1") end, subjstrings0 = function (o) return ParseTree{}:copywithsubj(o) end, subjstrings = function (o) return ParseTree.subjstrings0(ParseTree.deletestrings(o)) end, __index = { cot = function (pt,str) return ParseTree_cot(str) end, psubj = function (pt,pos1,pos2) return subj:sub(pos1,pos2-1) end, osubj = function (pt,o) return pt:psubj(o.b, o.e) end, isast = function (pt,o) return otype(o) == "AST" end, -- copy0 = function (pt,ast) return AST {[0]=ast[0], b=ast.b, e=ast.e} end, add1 = function (pt,o,a) if a ~= nil then table.insert(o,a) end end, adds = function (pt,o,...) local as = pack(...) for i=1,as.n do pt:add1(o,as[i]) end end, mkstr1 = function (pt,str) return "."..str.."." end, mkstr0 = function (pt,str) return nil end, copyo = function (pt,o,mkstr) if pt:isast(o) then local o2 = pt:copy0(o) for i=1,#o do pt:adds(o2, pt:copyo(o[i], mkstr)) end return o2 else return pt[mkstr](pt, o) end end, -- mksubj0 = function (pt,pos1,pos2) return mkast("(subj)", pt:psubj(pos1,pos2)) end, mksubj = function (pt,pos1,pos2) if pos1 < pos2 then return pt:mksubj0(pos1,pos2) end end, copywithsubj = function (pt,o) if not pt:isast(o) then error("Not an AST!") end local o2 = pt:copy0(o) local pos = o.b local add = function (o3) pt:add1(o2,o3) end local addsubj = function (pos1,pos2) add(pt:mksubj(pos1,pos2)) end if #o == 0 then addsubj(o.b, o.e) else for i=1,#o do addsubj(pos, o[i].b) add(pt:copywithsubj(o[i])) pos = o[i].e end addsubj(o[#o].e, o.e) end return o2 end, -- underbracify = function (pt, o) if not pt:isast(o) then print(o); error("^ Not an AST!") end if o[0] == "(subj)" then return o end local o1 = mkast("<>", o[0]) local o2 = mkast(".") for i=1,#o do table.insert(o2, pt:underbracify(o[i])) end return mkast("und", o2, o1) end, }, } -- «ParseTree-tests» (to ".ParseTree-tests") -- (find-angg "LUA/ELpeg1.lua" "totex-tests") --[==[ * (show2-use "/tmp/") * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ParseTree2.lua" o = gr:cm0("Stmt", "if (x>9) { x=0; y=y+1;}") = o pt = ParseTree {} o0 = pt:copyo(o, "mkstr0") o1 = pt:copyo(o, "mkstr1") = o1 = o0 o9 = pt:copywithsubj(o0) o10 = pt:underbracify(o9) -- = o9 -- = o10 = o10:show {em=1} * (etv) = Show.log = defs -- (find-angg "LUA/Co1.lua" "Co-tests") -- Test this: = ParseTree_co = ParseTree_co:add(" ", "\\textvisiblespace ") = ParseTree_co:add(" ", ".") --]==] --[[ * (eepitch-lua51) * (eepitch-kill) * (eepitch-lua51) dofile "ParseTree2.lua" o = gr:cm0("Stmt", "if (x>9) { x=0; y=y+1;}") = o = copyo(o) --]] -- Local Variables: -- coding: utf-8-unix -- End: