[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Need lpeg hint
- From: Peter Cawley <lua@...>
- Date: Sat, 13 Aug 2011 21:26:51 +0100
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.