[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: LPeg indent/whitespace based grammar
- From: Matthias Dörfelt <lists@...>
- Date: Tue, 11 Jul 2017 23:00:00 +0200
Awesome thanks, reading your examples really helps me grasping most of the core ideas of LPeg and re!!
> On Jul 11, 2017, at 20:51, Duncan Cross <duncan.cross@gmail.com> wrote:
>
> On Sat, Jul 8, 2017 at 8:12 PM, Matthias Dörfelt <lists@mokafolio.de> wrote:
>> I tried to do so using table and named group capture, but I can’t for the
>> life of me figure out how to dynamically set the name of the group capture.
>> Will I have to write a custom helper function to achieve this or is there a
>> pure re way?
>
> You do need to use a function for this -- re is only a thin layer on
> top of the same basic primitives as lpeg itself, and lpeg.Cg() takes a
> constant value, not a pattern capture, for the group name specifier.
>
> One approach is to capture an array of key/value pair objects, and
> then use a function capture to transform this array into an object
> with named fields. Something like this:
>
> --
> local re = require 're'
>
> local fields = re.compile([[
> fields <- {| <kvpair>* !. |} -> kvpairs_to_fields
>
> kvpair <- {| %s* {:key: <key> :} %s* '=' %s* {:value: <value> :} %s* |}
> key <- [a-zA-Z_] [a-zA-Z_0-9]*
> value <- <single_quoted> / <double_quoted>
> single_quoted <- ['] { [^']* } [']
> double_quoted <- ["] { [^"]* } ["]
> ]], {
> kvpairs_to_fields = function(kvpairs)
> local attrs = {}
> for _, kv in ipairs(kvpairs) do
> attrs[kv.key] = kv.value
> end
> return attrs
> end;
> })
>
> for k,v in pairs(fields:match[[ a="one" b = 'two' c="three" ]]) do
> print(k, v)
> end
> --
>
> -Duncan
>
>