Many years ago, when I started programming, my dream was to write
games. I failed miserably in that, but I became fascinated by
languages, and I discovered Forth - that was perfect for writing
languages whose syntax was as simple as possible. Then I switched to
GNU/Linux and I had a series of favorite languages; at some point I
discovered Lua, that became not only my favorite language but also my
favorite tool for implementing other languages. One of the main
libraries of Lua is something called LPeg, that lets "people"
implement complex parsers in just a few lines of code using PEGs -
Parsing Expression Grammars.
I've put the "people" in the last paragraph between quotes because for
many years I wasn't included in the "people who can implement complex
parsers with LPeg"… lots of things in LPeg didn't make sense to me,
and I couldn't visualize how it worked. Something was missing - some
diagrams, maybe?
The main tool for drawing diagrams in LaTeX is something called TikZ,
that is HUGE - its manual has over 1000 pages. TikZ includes lots of
libraries and extensions, and each one of these libraries and
extensions extends TikZ's core language with some extra constructs.
I don't know anyone - except for a handful of experts - who knows what
is the "core language" of Tikz, that lies, or that should lie, below
all these extensions… all of my friends who use TikZ are just
"users" of TikZ - they've learned some parts of TikZ by starting with
exemples, and by then modifying these examples mostly by trial and
error. In particular, no one among my friends knows how styles in TikZ
really work; styles are implemented using "keys", that are hard to
inspect from a running TeX - see [1] - and I found the chapter on "key
management" in the manual very hard to understand. It feels as if
something is missing from it… some diagrams, maybe?
In my day job I am a mathematician. I work in a federal university in
Brazil, and besides teaching I do some research - mostly in areas in
which the papers and theses have lots of diagrams, of many different
kinds, and in which people use zillions of different programs to draw
their diagrams. Every time that I see those diagrams I think "wow, I
need to learn how to draw diagrams like that!", but until a few
months ago this seemed to be impossible, or very hard, or very
painful…
This presentation will be about a point in which all these ideas
intersect. I am the author of an Emacs package called eev, that
encourages using REPLs in a certain way; Lua can be used in several
different styles, and if we use it in a certain way that most people
hate - with lots of globals, and with an implementation of OO that
makes everything inspectable and modifiable - then it becomes very
REPL-friendly; there is an extension of LPeg called LPegRex ([2],
[3]), that I found promising but hard to use, so I rewrote some parts
of it to make them more REPL-friendly, and to make it print its ASTs
in 2D ASCII art. The core of my presentation will be about how I am
using REPLs written in Lua to write grammars, parsers, and tools to
generate many kinds of diagrams, and how I am using these diagrams to
document both my own code and other people's programs - the parts of
them in which some diagrams seem to be missing. My hope is that people
will find these ideas easy to port to other languages besides Lua, to
other tools for generating diagrams besides LaTeX - SVG, maybe? - and
to other ways to use REPLs in Emacs besides eev. Some ideas in this
presentation were inspired by the blog post [4].
Magic is good as long as you have the option to look behind the
scenes when you want! Imagine if all code was assembly
language.
hi edrx! =) great talk
A :I didn't create a git repo with the code yet because I don't have any idea if anyone would want to test it today... everything is made to be used with this interface, http://anggtwu.net/eepitch.html
Q: is the code available as a tarball perhaps? or not at all yet?
as I know very few people who use eev - and who already use that interface - I wanted to ask them if they'd be ok with installing some files in ~/LUA/ and ~/LATEX/, or if they really needed to use other directories, or what... the things that are to be installed in ~/LUA/ are in a tarball, but a few of the files require some files in ~/LATEX/. I'm preparing the LATEX/ directory of the tarball now and I'll announce it on the eev mailing list soon
Dealing with diagrams with Emacs is tricky. Having documented examples of that is nice and would be helpful
A: I guess that the ideas that I presented would be easy to adapt to SVG diagrams, and to some packages that use Javascript to generate their diagram... but I don't want to write the code for SVG and for js diagrams all by myself. what do you use - or what have tried to use - to generate diagrams?
i've personally tried using a bunch of different tools but never found anything that fully clicked for me or was remotely pleasant to use. i guess 'draw.io' is decent, but something in Emacs would be awesome
do you think that musa's way to making emacs run javascript could work for draw.io?
hmm no clue tbh, worth trying to ask him. but i must say i'm not super enthused about embedding js in emacs
having tried most things (from exwm to org-protocol, to devtools debug protocol, and what not), I've converged on small personal extension that loads across browsers, locally, and stay connected with Emacs via the very useful emacs-websocket package, to interact both with the internal state of the browser (windows, tabs, etc.) and intra-page
Hi! My name is Eduardo Ochsand the title of this talk is: REPLsin strange places - Lua, LateX, LPeg, LPegRex,and TikZ. I'm the author of an Emacspackage called eev, and this is a talkat the EmacsConf 2023, that is happening inDecember 2023, at the internets.
This is one of theexamples of diagrams that we aregoing to see - let me show how I generateit... one second,I have to use a smaller font here...this is a file called ParseTree2.lua...let me go back to this block of tests again...and now if I runthis...we get these outputs here at theright, and then in this line here itgenerates a PDF, and if I type f8 here itshows the PDF in the lower right window.
Let me start by explainingbriefly what is eev.First: it is something thatappeared by accident in the mid-90s - Iexplained this story in mypresentation at the EmacsConf 2019...it's a package... it's an Emacspackage that is part of ELPA... it has atleast 10 users - those are the onesthat I know by name...eev means `emacs-execute-verbosely'...eev is something that treats eval-last-sexpas the central feature of Emacs...eev blurs the distinction betweenprogrammers and users, and it replacesthe slogan "users should not be forced tosee Lisp", that is something that RichardStallman told me once, by "users should seeLisp instead of buttons" and "new usersshould see Lisp in the first 5 minutes"...I'm going to showsome examples of that soon.Eev uses code in comments a lot,and also tests in comments...I changed my way of presenting itand it became very REPL-centricin the last few years, in thesense that I start by explaining itsmain features by its support for REPLs...eev supposesthat we want to keepexecutable notes of everything - I'm alsogoing to show examples of this in asecond... eev has lots of "videos forpeople who hate videos", and it tries todo everything with very little magic andwithout black boxes - I'm going to explainmany of these things very soon.
This is a figure that that I'm goingto show in details soon, that isabout something important about Lua...the font is very bad now, so let mechange the font... the figure is this one...and...what most people do when theyvisit a file with somethinginteresting on it is that they just gothere and they set a bookmark there, orthey put the position in a register...but I prefer to keeplinks to everything that is interestingas elisp hyperlinks. So, for example, this isan elisp hyperlink to a file, that goesto this anchor here, and to this stringafter this anchor... this is a variantthat opens that file in the windowat the right -here... and this isa sexp that changes the font. Ihave a command with a very short namethat does that, but Iprefer to keep that as a one-liner.About the videos... we can seethe list of first-class videos of eevby executing this, M-x find-1stclassvideos,or by running this alias here, M-x 1c...and then what we see is this...the first sexp hereregenerates this buffer - so we can make amess here and then run this and theoriginal buffer is regenerated again ina clean way...each of these things hereopens a buffer with information abouta video... let me take a specificexample here... this video here is aboutone of the ancestors of this talk, thatis a library that I wrotefor creating diagrams in LaTeX usinga package called Pict2e using REPLs...anyway...the thing is that if werun a sexp like this one and we don'thave a local copy of the video eevwill try to download to the local copy -and instead of doing that by askingsomething like "do you want meto download the local copy? Blahblah blah blah blah..." it simply opens abuffer like this, I mean, if we don'thave a local copy yet it will open abuffer like this one, in which thesethings here in comments are links to thedocumentation... I mean, this thing hereexplains the idea of local copiesof files from the internet...there are more details here, and here...and this is a script that wecan execute line by line, so instead ofthis script being hidden behind thebutton that we just press after aquestion like "Do you want me to dosomething blah blah blah? Yes or no?"the script is visible here and we canexecute it step by step... it creates aterminal with a shell here in theright window, and when we type f8 inone of these lines here the lines aresent... (...) so this is goingto download a copy of the video... thewget says that I already have a copy ofthe video and its subtitles... and so on.And after getting a copy of the videowe can run this sexp here and it displaysthe video.I said that eev has lots of"videos for people who hate videos", andthe idea is that very fewpeople are going to watch the videos inreal time... and most of the people thatI know - or: most of the people thatare interested in eev in someway... they are going to watch justsmall sections of the video, and most ofthe time they're just going to read thesubtitles of the video. So, for eachone of the videos we have a pageabout the video... let me see if Ihave internet here... yes. This is apage...and usually these pages have a linkto another page thathas all the subtitles of thevideo... uh, wherever... in this oneit's not so visible...but anyway, there are severalways of accessing the subtitles of thevideo, and one of the ways is by runningthis sexp here,that opens a file in Lua that iswhat I use to generate thesubtitles.Anyway... by the way, these things... eachone of these things here is a hyperlinkto a position of the video, so if I typethis the right way it goes to thatposition. Anyway, let me go back...also, the tutorials of eev... the"intros" of eev, that start with "find-" andend with "-intro", they have lots of blocksthat say "[Video links:]", like this one, andthese blocks have links to positionsin videos, and if we don't have a localcopy of the video yet the thing showsus a script that lets us download thelocal copy.Anyway, I said that I was goingto explain what I mean by "magic" and"black boxes".this is something that I've beentrying to explain for a long time, and Ithink that I got a very good explanationabout that in a video that I madeabout something called eev-wconfig, thatis a tool for configuring eev onWindows without "magic" - without buttonsthat do things without explaining whatthey're doing.This is a part of the subtitlesof the video, let me read that...eev-wconfig is an attempt to solve theproblem of how to install these thingson Windows both without magic and withvery littlemagic. Remember this slogan: "anysufficiently advanced technology isindistinguishable frommagic". Here in this video I'm going touse the term magic as a shorthandfor sufficiently advanced technology,that is something that is complex andnon-obvious and that isindistinguishable from magic in thesense of being almost impossible tounderstand. And I'm also going to use athe term "black box" as a near-synonym formagic, and sometimes the term"black box" is more convenient even thoughit's a bit longer - it has moreletters - because when I use the termblack box it invites us to useexpressions like "opening the black box",and I'm going to use thatexpression a lot.Now let me try to explain what is...sorry, let me change the font...what is Lua. Lua is a minimalisticlanguage, in the sense of"batteries not included"... it usesassociative tables for most of its datastructures...and it is so minimalisticthat its default print function, whenwe tell... when we create an associativetable and we ask it to print...when we ask "print" to print anassociative table it just prints theaddress of the table. Here are someexamples... here is a table, and when weask "print" to print it it just saysthat it's the table at this address here.So, one of things that that mostpeople do when they start using Lua isthat either they download a package witha pretty-printing function or they writetheir own pretty-printing functions. Myown pretty-printing function is calledPP, with upper case letters, and it workslike this...and it prints associative tablesin a way like this. It says that forthe key 1 the the value associated toit is 2, for the key 2 the value is3, and for the key 3 the value is 5.When I started using Lua one of myfavorite languages was also a languagethat used associative tables a lot -it was called Icon...and I had to write my ownpretty-printing functions for Icon, soI just had to port my pretty-printingfunctions to Lua... and my firstversion looked at something like this... itjust had some some global functions... lotsof them, actually...and after a while I rewrote it, and Irewrote it again, and again, and again, andthis is one of the versions of that,is not even the default at thispoint..."Tos" is for "to string"...and this is a demo...it's very modular, so it's easy to replaceparts of it, or to toggle flags... and thisis an example. If I try to print thetable of methods for a certainclass... I will need a smaller font...it prints the table like this, with thenames of the methods and then links tothe source code of the functions...these links only make sense in Emacs andin eev...and when we run a link like this one...it shows the source code in thewindow at the right. So, for somefunctions the source code is three lines,for other ones it's one line... andwhatever. Anyway, let me goback... Lua can be used in many differentstyles... most people hate other people'sstyles... when I started using it in theyear 2000 I learned most of the basiclanguage in a single day - it was verysimilar to things that I was alreadyusing... and then I rewrote the the mini-language that I was using togenerate the HTML for my pagesin Lua... actually I had to rewrite itmany times, but the first version Icertainly did in my first weeks or firstmonths using Lua...In the beginning I was just usingit for writing programs that eitherdidn't take any input at all - becausethe input was already in the source file -or that worked as Unix programs,that would read filesand process these files in some wayand output something.I mentioned the "basic language" here...I only learned how to use closures,metatables, and coroutines many years later...in the beginning, when I started using Lua,it didn't have a package manager...it appeared later, it is calledLuarocks... it has had this packagemanager for several years, mostof the rocks for Luarocks are poorlydocumented and hacker-unfriendly,so you can't rely just on thedocumentation and you can't rely just on thesource code, because, I mean... if you area genius of course you can, but forpeople who are either lazy, or dumb, orwhatever, like me, or unfocused...the source code is hard tounderstand and hard to tinker with.Some rocks are excellent. Thebest rocks are well documentedbut they are hacker-unfriendlyin a sense that I hope thatI'll be able to explain soon.The best rocks use localvariables and metatables a lot -so if you are beginnerlearning Lua you're not going tounderstand what their source code do...they use lots of dirty tricks.
Let me talk a bit about objectorientation in Lua. It can be done inmany ways...the main book about Lua, called"Programming in Lua", by one of the authorsof the language, Roberto Ierusalimschy,presents several ways of doingobject orientation in Lua... I hated allof these ways - and also the ways that Itried from the rocks.And then I wrote my own wayof doing object orientation in Lua... it'svery minimalistic, it's in this file here,eoo.lua... the main code is just this fivelines here...and here's an example of how it works.Here we define the class Vector,with some metamethods...this metamethod here will tell Luawhat to do when theuser asks to add two vectors, this onehere tells Lua what to do when the userasks Lua to convert a vector to a string,and... whatever, this one issomething that I'm going to explain in asecond. So, here we create a vector withthese coordinates, 3 and 4... here we createanother Vector... if we "print" here then Luauses this function here, in the __tostring...if we add the two vectors it uses thisfunction here, in the __add metamethod, andif we run the method :norm...it is defined here, in the table __index.Anyway...Even this thing being so small I usedto forget how its innards worked allthe time. Actually I always forget howthings work and I have to remember themsomehow... and I have to havetricks for remembering, and tricks forsummarizing things, and diagrams, and soon. And every time that I forgot how thisthing worked I went back to thesource code, and then I looked at thediagrams... or, of course, in thefirst times I had to draw the diagrams...and I run the examples, and of course inin the beginning I thought that the codewas clear and my examples were verybrief, and so I had to rewrite theexamples many times until they became,let's say...perfect.I was saying that Lua can be used inmany ways, and in my way of using Lua - inmy favorite way - everything can beinspected and modified from REPLs,like we can do in Emacs and in SmallTalk,or sort of. So, in myfavorite way of using Lua there's nosecurity at all, everything can bechanged at all times.Of course most people hate that...
My init file has lots of classes... by theway, instead of keeping many small fileswith many things I put lots of stuffin just one big init file.My init file has lots of classes,and lots of global functions, andlots of cruft - and people hate that,of course. This is an example...this is the index at the topof my init file,the classes start here, and thenwe have some functions, andthen we have functions that loadcertain packages, and then we have... cruft.Whatever.Most people think that my styleof using Lua is dirty, and dangerous...and they wouldn't touch my Lua codewith a 10 feet pole... but most of thethings that I'm going to present here inthis presentation are ideas that shouldbe easy to port to other environmentsand other languages, especially thediagrams... so the code is not so important.
Now let me talk a bit about LuaLaTeX,that is LaTeX with a Lua interpreterembedded inside, and two waysof generating pictures in LaTeX: TikZ,that is very famous, and Pict2e, that is notvery famous and that is very low level...and I think that not many people use it.I said before that when Ilearned Lua I realized that it wasvery good for writing littlelanguages. I was doing my PhD at thetime and typesetting the diagrams formy PhD thesis was very boring, soone of the things that I did was that Icreated a little language for typesettingthe diagrams for me. it wascalled Dednat because initiallyit only generated diagrams forNatural Deduction, and then it hadseveral versions...these are the slides for mypresentation about Dednat6... "Dednat6 isan extensible semi-preprocessor forLuaLaTeX that understands diagrams inASCII art"... in the sense that when I havea .tex file that has this, and whenDednat6 is loaded,when I give the right commandsDednat6 interprets this block here assomething that defines thisdiagram... oops, sorry, it interprets thisdiagram here, this diagram incomments here, as something that definesa diagram called foo... a deduction calledfoo, and it generates this code here...so that we can just invokethe definition of thededuction by typing \ded{foo}.And Dednat6 alsosupports another language for typesettingbidimensional diagrams witharrows and stuff for category Theory andblah blah blah... the specifications ofthese diagrams look like this...here is a... sorry, here is a very goodexample, this is a huge diagram...sorry, one second...so, the source code that generatesthis diagram here is just this thing atthe left, so it's very visual... we cantypeset the diagram in ASCII art here andthen in this part here we tell howthe nodes are to be joined, whicharrows have to to have annotations, andso on...and this language is extensible inthe sense that... uh, where's that...here: comments that start with "%:"are interpreted asdefinitions for tree diagrams,lines that start with "%D"define 2D diagrams with arrows andstuff, and lines that start with "%L"contain blocks of Lua codethat we can use to extend the interpreteron-the-fly...anyway, here are some recentexamples of diagrams that I usedDednat6 to typeset... this diagramhere was generated by thisspecification here...and this diagram here with thecurved arrows was generated by thisspecification here.So, Dednat6 was very easy to extend,and at some point I started to use itto generate diagrams using Pict2e -mainly for the classes that I giveat the University... I teach mathematics andwhatever... in a bad place. Whatever...Let me show an animation... here is adiagram that I generated with Dednat6,and it is a flip book animation, like... wetype PgUp and PgDn and we goto the next page of the book and to theprevious page of the book...and here is the source code that generatesthat. This source code is not very visual,so it's quite clumsy to edit thatdiagram directly in the .tex file likethat...
These diagrams were inspiredby something called my Manim, that...I forgot the name of the guy, butit's a guy that makes many videos aboutMathematics, and he created this librarycalled Manim for generating hisanimations, and other people adaptedhis library to make it more accessible...I tried to learn it, buteach animation, even an animationthat has very few frames... eachanimation took ages to render, so itwasn't fun... and animations in PDFs canbe rendered in seconds. So thesethings were fun for me, because my laptopis very very slow, and my Manim was not fun.
Anyway, writing code like thisinside a .tex file was not veryfun because it was hard todebug... so in 2022 I started to playwith ways of generating thesediagrams from REPLs, and I found away for Pict2e and a way for TikZ...each one of these ways became a video...if you go to the list of first-classvideos of eev you're going to seethat there's a video about Pict2e herehere and a video about TikZ...here you have some some informationlike length, an explanation, etc...and here are the pages for these videos.My page about the video about Pict2elooks like this, it has some diagrams...whatever... and this one is muchnicer, and a lot of peoplewatched that video... I mean, I thinkthat 250 people watched it - for me that'sa million of people...and this video is about how toextract diagrams from the manual... fromthe TikZ manual and how to run thoseexamples in a REPL and modifythem bit by bit... this is a ascreenshot... but let me go back.At that point these things were justprototypes, the code was not very nice...and in this year I wrote... I was ableto unify those two ways of generating PDFs,the one for TikZ and the one for Pict2e,and I unified them with many otherthings that generated diagrams.The basis of these things issomething called Show2.lua... I'm not goingto show its details now, but itsextension that generates TikZ codeis just this, so we can specify adiagram with just a block like this,and then uh if werun :show00() it returns a stringthat is just the body... the innerbody of the .tex file, if we run this wesee the whole .tex file, and if we runthis we save the .tex file and wecompile the .tex file to generate a PDF...and if we run this we show the PDF inthe lower right window.And that's the same thing for allmy recent programs that generatePDFs - they are allintegrated... here is the one that...the basis for all my modules that generatediagrams with Pict2e...its demos are not very interesting,so let me show some demos ofextensions that do interesting things...so, this is a diagram that I createdby editing it in a REPL...I create several Pict objects here...and if I execute this itcompiles an object, generates a PDF, andif I tap this... here is the PDF.And if I just ask Lua todisplay what is "pux", here,it shows the source code in Pict2eof the diagram... and thenice thing is that it is indented, soit's easy to debug the Pict2e code.If anyone is interested themodule that does the tricks forindentation is very easy to understand...it has lots of tests and test blocks,and I think that its datastructures are easy to understand.Anyway... here is anotherexample. The :show() ishere... it generates a 3D diagram.
Now let me talk about parsers andREPLs in VERY strange places... I mean,using REPLs to build parsers step by stepand" replacing parts by more complexparts. So, I said that Lua is veryminimalistic, and everybody knows thatimplementations of regular expressionsare big and complex..so, instead of coming withfull regular expressions Lua comes withsomething called "patterns" and alibrary function called "string.match".Here isa copy of the part of the manual thatexplains the syntax... a part of thesyntax of of patterns... here's howstring.match is described in themanual - it's just this... "looks forthe first match of pattern in the stringas blah blah blah"... and then we have togo to the other section of the menualthat explains patterns.Lua patterns are so simple,so limited, that they don't evenhave the the alternation operator...here is how it is described in theelisp manual -backslash-pipe specifiesan alternative, blah blah blah.When we want to to build morecomplex... regular expressions,patterns, grammars, etc... we have to usean external library for that... no,sorry, a library that is externalbut that was written by one of theauthors of Lua itself. This libraryis called Lpeg, and its manual says..."Lpeg is a new pattern matching library forLua based on Parsing Expression Grammars(PEGs)". The manual is very terse, Ifound it incredibly hard to read... itdoesn't have any diagrams - it has someexamples, though... and the Lua Wikihas a big page called Lpeg Tutorialwith lots of examples...but it it also doesn't havediagrams and I found some thingsincredibly hard to understand.For example, this is something that is inthe the manual of Lpeg that I saw and Ithought: "Wow, great! This makes all senseand is going to be very useful!"...it's a way to to buildgrammars that can be recursive,and they sort of can encode BNFgrammars... we just have to translate theBNF a bit to get rid of somerecursions and to translate them tosomething else.And the manual also has some thingsthat I thought: "Oh, no! I don't have anyidea of what this thing does"... and in factI saw these things for the firsttime more than 10 years ago and theyonly started to make sense one year ago.One example is group captures.Lpeg also comes with amodule called the Re module... let mepronounce as it in Portuguese - the Remodule... its manual says: "The Remodule (provided by the file re.lua in thedistribution) supports a somewhat conventionalregular expression syntax for pattern usagewithin lpeg"... andthis is a quick reference... thisthing is very brief, it has some niceexamples but it's hard to understand anyway...and here are some comments aboutmy attempts to learn Re.lua. This isa class... in this case it's a very smallclass... this file implements a :pm()method - I'm going to show examples ofother :pm() methods very soon - so, this isa :pm() method for Re.lua that lets uscompare the syntax of Lua patterns, Lpeg,and Re... let's see this example here... so,if we run this it loads my version oflpeg... no, sorry, my version of lpegrex...and it shows that when we applythe :pm() method to this Lua pattern, thislpeg pattern, and this Re patternthey all give the same results. So we canuse this thing... this kind of thing hereto show how to translate from Luapatterns, that are familiar becausethey're similar to regular expressions,only weaker...to lpeg, that is super weirdand to Re, that is not so weird.Anyway, the comment says that in 2012I had a project that needed aprecedence passer that could parsearithmetical expressions with the rightprecedences... and at that point I wasstill struggling with pure lpeg, and Icouldn't do much with it, so I tried tolearn Re.lua instead, and I wrote this oldclass here...that allowed me to use a preprocessoron patterns for Lua. And the thing is thatwith this preprocessor I couldspecify precedence grammars using thisthing here, that worked, but was superclumsy... and I gave up after a few attempts.and in 2022 I heard about somethingcalled lpegrex,that was a... a kind of extension or Re,and it was much more powerful than re.lua,but after a while I realized that ithad the same defects as re.lua...and let me explain that, becauseit has all to do with the things aboutblack boxes and magic that I told in thebeginning. Both... I mean, sorry, neitherre.lua or lpegrex had some features thatI needed... they didn't let us explore...sorry, they received a pattern that wasspecified as a string, and it convertedthat into an lpeg pattern, but it didn'tlet us explore the the lpeg patternsthat it generated...their code was written in a waythat was REPL-unfriendly - Icouldn't modify parts of the codebit by bit in a REPL and try to changethe code without changing theoriginal file... the code was veryhard to explore, to hack, and to extend -in my opinion... the documentation was notvery clear... and I sent one or two messagesto the the developer of lpegrex and...he was too busy to help me. Heanswered it very briefly, and, uh, to behonest I felt... rejected. I felt that Iwasn't doing anything interesting...whatever, whatever...So, in 2022 I was trying to learn lpegrexbecause I was thinking that it wouldsolve my problems - but it didn't...it didn't have the features that I needed,it was hard to extend, hard to explore,and hard to debug, and Idecided to rewrite it in a morehacker-friendly way - in the sense that...was modular, and I could replace anypart of the module from a REPL...
My version of it was called ELpeg1.lua...and I decided that in my version Iwouldn't have the part thatreceives a grammar specified as a stringand converts that to lpeg... I wouldjust have the backend part, that are thefunctions in lpeg that let us specifypowerful grammars.Let me go back. Let me explain abit about lpeg... Lua hascoercions: the + expects to receivetrue numbers, and if one of its arguments,or both of them, are strings, it convertsthe string... the strings to numbers so inthis case here, 2+"3",it returns the number 5,and this is the concatenationoperator... it expects to receivestrings, so in this case it willconvert the number 2 to the string "2",and the concatenation of thes twothings will be 23... oops, sorry, "23"as a string.Lpeg also has some coercions.I usually set theseglobals to let me write my grammarsin a very compact way, so insteadof lpeg.B, lpeg.C, etc I use these globals,like uppercase B, uppercase C, and so on...and with these globals I can writethings like this: C(1)*"_"...and lpeg knows that lpeg.C...it sort of expands this to lpeg.C,but lpeg.C expects to receivean lpeg pattern, and 1 is not yet anlpeg pattern, so it is coerced into anlpeg pattern by calling lpeg.P,so this short thing here becomesequivalent to lpeg.C(lpeg.P(1)), and themultiplication, when at least one of itsarguments is an lpeg pattern... it expectsto receive two lpeg patterns, and inthis case the one at the right isjust a string, so it is coerced to an lpegpattern by using lpeg.P.With this idea we can sort ofunderstand the comparison here. I mean,let me run it again... this first part isvery similar to a regular expressionhere at the left...and when we apply this... Lua patternto this subject here the resultis this thing here, this thing, thisthing and this thing... I'm going tocall each one of these results"captures", so each of these thingsbetween parentheses "captures" a substringof the original string and thesecaptured substrings are returned in acertain order. Here is how to express thesame thing in lpeg...it's very cryptic but it's agood way to understand the some basicoperators of lpeg, I mean we can look atthe manual and understand andwhat C, S and R do, and alsoexponentiation... and this strange thinghere receives this string here, runsa function that I have defined, thatconverts it to an object of a certainclass, and that classrepresents Re patterns, so this thingis treated as a pattern for re.lua,and it is matched against the string,and it returns the same thing as theother one.Also, this thing here also has acomparison with lpegrex, but thesepatterns are very trivial, theydon't do anything very strange...so let's go back and see whatkinds of very strange things there are.Here is the page of lpegrex at github,here's the documentation...it's relatively brief,it explains lpegrex as being anextension of Re.lua, so it explainsmainly the additional features... here is aquick reference that explains only theadditional features...some of the these thingsI was able to understandby struggling a lot, and some I wasn'table to even by spending several eveningstry to to build examples...and this is something very nice. Lpegrexcomes with some example parsers... andhere is a parser that parses the Luagrammar - I mean, this is the the grammarfor Lua 5.4 at the end of thereference manual... it's just this... thisis in a kind of BNF, and this is the BNFtranslatedto the language of lpegrex, so thisthing uses many constructions that arein re.lua and some extra constructions thatare described here... and with theseexamples I was able to to understandsome of the...of these things here that aredescribed here in the quickreference - but not all.So, I wasn't able to use lpegrexby itself, because some things didn'tmake much sense, and I decided toreimplement it in my own style,because that would be a way to map...to at the very least map what I hadunderstood and what I didn't, learnone feature at a time, do comparisons, andso on.Here I pointed to two features of lpeg...in one I said "Oh, great! This thing canbe used to to define grammars, evenrecursive grammars", and so on...and this is an "Oh, no!" feature - onething that didn't make any sense at all...group captures. One thing that I did tounderstand group captures was torepresent them as diagrams. Of course inthe beginning I was drawing thesediagrams by hand, but then I realizedthat I could use the bits of lpegthat I already knew to build a grammarthat would parse a little language andgenerate these diagrams in LaTeX, and I wasable to make this.In this diagram herethis thing above the arrow is Lua code...a piece of Lua code thatspecifies an lpeg pattern... thisthing here at the top is the string thatis being matched, and the things belowthe underbraces are the captures thateach thing... sorry, that each thingcaptures.For example, this underbrace herecorresponds to this pattern here,that parses a single character butdoesn't return any captures, this thinghere parses a single "b" and doesn'treturn any captures, this thing hereparses a single character and capturesit, and this thing here parses thecharacter "d" and captures it... and thisother thing here transforms thispattern into another pattern...returns first a capture with allthe string that was parsed by thispattern here, and then all the capturesreturned by this thing here beforethe ":".So, this was a way to buildconcrete examples for things that thelpag manual was explaining in a very terseway, and it worked for me - some thingsthat were verymysterious started to make sense, and Istarted to have intelligent questionsto ask in the mailing list.And with that I was able tounderstand what are group captures,and group captures that receive a name...Well, let me explain what this does.This thing here captures... sorry, parsesthe empty string and returns this as aconstant... so, this is something thatdoesn't exist in regular expressions...it parses nothing andreturns this as a capture... then thisthing here returns these twoconstants here, and parses the emptystring, and this thing here convertsthe results of this thing here into agroup capture, and stores it in the label"d"... and then here's another constantcapture.
And I realized that these thingshere were similar to how Luaspecifies building lists...when we build... sorry, tables. Whenwe build a table, and we say that thefirst element of the table is here, thiselement is put at the end of the table...when after the that would say d=42...we are putting the 42in the the slot whose key is "d".This was happening with lpeg captures,but there was something very strange...these group captures could holdmore than one capture - more than onevalue... so there was something betweenlists and tables. I started to use thisnotation to...explain in my notation what theywere doing... many things startedto make sense, many mysterioussentences in the manual started tomake sense... but some didn't...but at least I was able to sendsome intelligent questions to themailing lis,t and the author of Lua andlpeg answered some of them...he was not very happy about myquestions - he... told me that thosediagrams were a waste of time, themanual was perfectly clear, and so on...whatever - but I was able to...so, it was weird, but I was able tounderstand lots of things from hisanswers. This is a copy of one ofmy messages, then there's another one,another one, some of them had diagrams...then he complained about these diagrams,he said that these things here, that looklike table constructors, "do not exist"...whatever... anyway, once I understoodgroup captures many featureswere very easy to understandand I started to be able to use lpeg toto build some very interesting things...I was able to reproduce someof the features that I saw in lpegrex -remember that this... where is that?this is the syntax of Lua... here -I was able to understandhow these things here were translated tolpeg code... to lpeg patternsby using group captures in a certainway... I was able to implement themin ELpeg1.lua...and after some time I was able to useELpeg1.lua to build grammars thatwere able to parsearithmetical expressions with theright precedence... and here's an examplein which I built the grammar step by step...and I test the current grammar, and Ireplace a bit, and then I test the newgrammar and so on...and you can see that the result isalways a tree that is drawn in anice two dimensional way...At this point these powers hereare returned as a list,as an operation "pow"with several arguments, here... and thenI apply a kind of parsing combinator,here... that transforms these trees intoother trees and with these combinatorshere I can specify that the "^" isassociative in a certain direction...that the "/" is associative inanother direction... the "-" usesthe same direction as a the "/",and so on... and they have theright precedences.So, here are the tests...here is my file ELpeg1.lua... it hasseveral classes, each class has testsafter it...I was able to implement somethingthat lpegrex has, that is called"keywords", that is very useful for parsingprograms in programming languages...I was able to implement somethingsimilar to the debugger... to thelpeg debugger lpeg uses... I wasfrustrated by some limitations ofthe lpeg debugger, and I implementedmy own that is, uh... much better!...Let me show something else... I wasable to translate a good part of theLua parser, here, to ELpeg1.lua... I haven'tfinished yet, but I have most of thethe translation here...and after having all that I was able tobuild other grammars very quickly...writing new parsers finally became fun.And here's one example that I showed in thebeginning.If I remember correctly...I took a figure from the Wikipedia...I don't have its link now...but I specified a grammar that parsesexactly the example that appearsin the Wikipedia...so, with my grammar, considering thatthe top level entry is "Stmt", when Iparse this string herethe result is this tree...and I can do some operations on that,I can define how this thing is to beconverted into LaTeX,I can define other operationsthat convert trees into other trees, andhere are some tests of these operations...This is what I showed in the beginning...I'm not going to explain all the detailsof this thing now...this :show() converts this thinginto LaTeX in the way specified by theseinstructions here, that says that...well, whatever...and here's the result - the LaTeXed result...and these diagrams here are generated bythis file here, that defines a simplegrammar that parses this thing here,and then LaTeXes it in a certain way, andand also tests to check if this code here...this Lua code that generates an lpeg grammar...parses this subject here andreturns the expected result...So: this is the code that Iwanted to show. I wanted to show manymore things but I wasn't able to preparethem before the conference... and I hopethat soon - for some value of "soon" -I'll be able to create REPL-basedtutorials for lpeg, Re, and ELpeg1.lua...where lpeg is something very famous,Re is a module of lpeg...I could also do something like thisfor lpegrex... and ELpeg1.lua isthe thing that I wrote, the one thathas test in comments, and the testsusually generate trees, and sometimesthey generate TeX code.Yeah, so that's it! I wanted topresent much more but I wasn't able toprepare it... so: sorry, thanks, bye! =)