[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Make peg.el a built-in library?
From: |
Stefan Monnier |
Subject: |
Re: Make peg.el a built-in library? |
Date: |
Thu, 30 Sep 2021 15:44:28 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
> Whether or not PEG gets added to core I'd like to propose some patches.
> The "peg-doc-patches.diff" attachment adds some documentation to the
> Commentary section, including an example grammar based on a
> much-simplified version of what gnus-search does.
Looks great, thanks.
> The peg-allow-symbols patch is more tentative. The issue is that _all_
> of the entry-points to peg code are macros, meaning you can't build your
> grammar up in a variable, and then pass that variable to any of
> `peg-run', `peg-parse', `with-peg-rules', etc. Nobody will evaluate the
> variable; you have to literally write the rules inside the
> `with-peg-rules' form. It seems like a fairly plausible use-case to
> store the rules in a variable or an option, even if you're not doing
> run-time manipulation of them. The only solution, as Adam found with
> org-ql, is to `eval' one of the macros.
>
> This doesn't seem necessary! The patch has `with-peg-rules' check if the
> rules are a symbol, and take the `symbol-value' if so. But I wonder if
> it wouldn't be nicer to break some of the code out: `peg-normalize'
> seems to be the entry-point for "compile this grammar", and that could
> be modified to work the way that some languages provide for pre-compiled
> regexps: a way to let the developer build and compile the grammar at
> load-time or launch-time, then feed the stored compiled version to
> parsing routines.
`peg` is the macro that's supposed to be this compilation step: you pass
it a PEX and you receive a value in return. It's a bit like `lambda`.
You can then use this value (a "peg matcher") to parse something by
passing it to `peg-run`.
So you can do
(let ((parser (peg PEX)))
...
(peg-run parser ...)
...)
What might still be missing, tho is a way to invoke this `parser` from
within a PEX. So we might want to add a new PEX form that would be akin
to `funcall`. We could name it `call`:
(let* ((parser (peg PEX))
...
(with-peg-rules
((foo ...)
(bar ... (call parser) ...)
(baz ...))
...))
so (peg-parse (call FORM)) would end up equivalent to (peg-run FORM ...).
WDYT?
Stefan