lua-users home
lua-l archive

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


On Sat, Aug 13, 2011 at 10:33 PM, Martin Kortmann <mail@kortmann.de> wrote:
>
> Am 13.08.2011 um 22:26 schrieb Peter Cawley:
>
>> On Sat, Aug 13, 2011 at 9:09 PM, Martin Kortmann <mail@kortmann.de> wrote:
>>>
>>> Am 13.08.2011 um 21:36 schrieb Peter Cawley:
>>>
>>>> On Sat, Aug 13, 2011 at 8:18 PM, Martin Kortmann <mail@kortmann.de> wrote:
>>>>> Hello all,
>>>>>
>>>>> I'm trying to learn the usage of lpeg and i need a push to the right direction on the following problem:
>>>>>
>>>>> I will parse files with the following structure:
>>>>>
>>>>> blockname1 {
>>>>>  key1 value1
>>>>>  key2 value2
>>>>>  blockname2 {
>>>>>    key3 value3
>>>>>    blockname3 {
>>>>>      key4 value4
>>>>>    }
>>>>>    key5 value5
>>>>>  }
>>>>> }
>>>>>
>>>>> there are named blocks of datas, the datas are several key/value pairs or other named blocks of datas. Seem simple, but i don't get a right grammar for this syntax.
>>>>> Can someone give me a start for this?
>>>>>
>>>>> Thanks Martin
>>>>
>>>> Very quickly thrown together, but seems to work for your example:
>>>> http://codepad.org/z49J4o8z
>>>>
>>>
>>>
>>> Thank you Peter, this seems to work. but why does the following code not work?
>>>
>>> local L = require "lpeg"
>>>
>>> local function makepairs(kvkv_array)
>>>  local t = {}
>>>  for i = 1, #kvkv_array, 2 do
>>>    t[kvkv_array[i]] = kvkv_array[i+1]
>>>  end
>>>  return t
>>> end
>>>
>>> local ws = L.S" \r\n\t"^0 -- whitespace
>>> local id = L.C(L.R("az","AZ","09")^1) -- identifiers
>>> local value = id -- values (currently same as identifiers)
>>>
>>> local grammar = L.P { "block",
>>>
>>>        entry = ws * id * ws * value + L.V('block'), -- key value OR block
>>>
>>>        block = ws * id * ws * "{" * (L.Ct(L.V"entry"^0) / makepairs) * ws * "}" / function(k, v) return {[k] = v} end;
>>>
>>> }
>>>
>>> local result = grammar:match[[
>>>
>>> blockname1 {
>>>  key1 value1
>>>  key2 value2
>>>  blockname2 {
>>>   key3 value3
>>>   blockname3 {
>>>     key4 value4
>>>   }
>>>   key5 value5
>>>  }
>>> }
>>>
>>> ]]
>>>
>>>
>>> Martin
>>
>> The "block" non-terminal generates one capture because the function
>> merges two captures into one. The "entry" non-terminal generates two
>> captures for a key/value pair, but only generates one capture for a
>> block. This then confuses makepairs, as it expected every match of the
>> "entry" non-terminal to produce two captures.
>>
>
>
> Hello Peter,
>
> but i can't see the difference between your example and my my code. Maybe there are too many trees in the wood...
> Where is the difference between your "pattern" and my "block"?

Your "block" has "/ function() ..." as part of it, causing that
function to be applied at every match of "block". My "pattern" has "/
function() ..." outside of the grammar, causing it to be applied only
to the top-level block.