lua-users home
lua-l archive

Re: LPeg indent/whitespace based grammar

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


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

AltStyle によって変換されたページ (->オリジナル) /