lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Chris Smith once stated:
> 
> > On 10 Aug 2023, at 23:07, Sean Conner <sean@conman.org> wrote:
> > 
> > It was thus said that the Great Chris Smith once stated:
> >> Hi,
> >> 
> >> Has anyone written an LPEG grammar for parsing S-expressions?
> > 
> >  Yes, and very simplistic S-expression grammar is:
> > 
> > local lisp = lpeg.P {
> >  'lisp',
> >  lisp  = lpeg.V"atom"  + lpeg.V"list",
> >  atom  = lpeg.V"space" * lpeg.C(lpeg.R("!'","*~")^1),   
> >  list  = lpeg.V"space" * lpeg.P'(' * lpeg.Ct((lpeg.V'list' + lpeg.V'atom')^0) * lpeg.P')',
> >  space = lpeg.S" \t\v\r\n"^0
> > }
> 
> Thank you, that is a bit simpler than the version I was hacking together,
> although I see it suffers from the same issue that mine had in that it is
> intolerant of trailing spaces.  For example ‘(a b c )’ won’t match.

  Ah.  That's an easy fix:

	list = lpeg.V"space" * lpeg.P'(' 
             * lpeg.Ct((lpeg.V'list' + lpeg.V'atom')^0)
             * lpeg.V"space" * lpeg.P')'

> I solved this in my version using the following:
> 
> space = lpeg.S" \t\v\r\n”
> opt_space = space^0
> delim = #(space^1 + ‘)’) * opt_space
> 
> Then adding *delim to the end of atom and list, but this seems a bit
> clumsy to me.  Is there a better way?  Is there a way to get LPeg to do a
> two-stage pass, so you can effectively say match all atoms first, then
> match lisp ignoring all spaces?

  No, unless you have two different LPEG expressions.

  -spc