[Top][All Lists]

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

Re: [PATCH] Re: Make peg.el a built-in library?

From: Ihor Radchenko
Subject: Re: [PATCH] Re: Make peg.el a built-in library?
Date: Thu, 17 Nov 2022 12:21:46 +0000

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

>>> +@item (* E)
>>> +Zero or more of an expression, as the regexp ``*''.
>>> +
>>> +@item (+ E)
>>> +One or more of an expression, as the regexp ``+''.
>> It is worth highlighting the greedy part here and referring to &A and
>> !A.
> I don't believe there is separate syntax for &A and !A -- those are
> written (if A) and (not A).

Indeed. I just felt lazy to write (if A) and (not A) and wrote &A and !A :)

The comment is suggesting to add reference to the (if A)/(not A) and the
"Writing PEGs" section.

>> Actions are only run when the expression matches; with point moved after
>> the match, right? What about &A and !A?
> That's right, actions only run if the parsing succeeds, and they run all
> at once at the end. Maybe I can move all discussons of parsing success
> vs failure into one place.

I think that there might be confusion here because people are used to
full success/full failure but not to partial success.

And (if A) feels even more confusing because it does not actually move
point and does not advance the parser. So, it is unclear what success
means and what is the buffer/stack context when action is executed.

>>> +@item (list E)
>>> +Match E, collect all values produced by E (and its sub-expressions)
>>> +into a list, and push that list to the stack.
>>> +@end table
>> This one is not very clear. Does it imply that E is recursively wrapped
>> into substring?
> It's not very clear because I don't fully understand it! It does not
> implicitly create any value-returning calls (such as `substring'). I
> think what it means is that, by default, values returned by actions are
> all spliced into a single flat list. If you need some of those values to
> be returned in a sub-list, you can use this form.
> It's a bit tricky to use because the E in (list E) could potentially
> descend many levels and branch out into any number of sub-expressions,
> so you need to have a clear mental model of what values might ultimately
> be coming out of E. I guess that's also true for the whole thing,
> though.

I also don't fully understand this, but I tried to play around with the

    ((name (substring (+ [word])) (* [blank]))
     (given-name name (not (eol)))
     (last-name (list name) (if (eol)))
     (full-name (list (+ given-name)) last-name))
  (peg-run (peg full-name)))

;; <point>Eric Edwin Abrahamsen

;; => (("Abrahamsen") ("Eric" "Edwin"))
;; Suggested stack states:
;; 1. nil
;; 2. Match Eric via given-name: ("Eric")
;; 3. Match Edwin via given-name: ("Edwin" "Eric")
;; 4. No more match for given-name. List operation: (("Eric" "Edwin"))
;; 5. Match Abrahamsen via last-name. ("Abrahamsen" ("Eric" "Edwin"))
;; 6. Done with last-name. List operation: (("Abrahamsen") ("Eric" "Edwin"))
;; 7. done

So, one may think that the stack values coming from E in (list E) are
simply reversed, wrapped into a list, and pushed back into the stack.
Kind of group operation.

Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]