[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- 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