|
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: