• Subject: Re: LPEG S-expression grammar
• From: Sean Conner <sean@...>
• Date: Fri, 11 Aug 2023 09:48:20 -0400

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