lua-users home
lua-l archive

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


  I keep finding myself with this issue when using LPeg.  I have some text I
need to parse and I want the results to go into a table.  Easy enough:

--[[========== CODE ==============]]

local dump = require "org.conman.table".dump
local re = require "re"

local G = [[

list            <- {| params* |}
params          <- transport
                /  maddr
                /  ttl
                /  userparm
                /  method
                /  lr
                /  xafi
                /  generic

transport       <- "transport=" {:transport: char+      :} %nl
maddr           <- "maddr="     {:maddr:     char+      :} %nl
ttl             <- "ttl="       {:ttl:       %d+        :} %nl
userparm        <- "user="      {:userp:     char+      :} %nl
method          <- "method="    {:method:    [A-Za-z]+  :} %nl
lr              <- "lr"         {:lr:        '' -> "lr" :} %nl
xafi            <- "x-afi="     {:xafi:      %d+        :} %nl

generic         <- { name ("=" char+ )? } %nl

char            <- [^%nl]+
name            <- [^=%nl]+
]]

parse = re.compile(G)

TEST = [[
transport=http
maddr=help
ttl=55
foobar=444k
snafu
user=blah
lr
method=post
x-afi=444
]]

x = parse:match(TEST)
dump("x",x)

--[[========== END OF LINE ============]]

This results in the following table:

x =
{
  [1] = "foobar=444k",
  [2] = "snafu",
  lr = "lr",
  xafi = "444",
  method = "post",
  ttl = "55",
  userp = "blah",
  maddr = "help",
  transport = "http",
}

  The problem I have are with the fields "foobar" and "snafu".  They aren't
defined, but I need to handle non-standard fields that might come up.  I
would like to have the results like:

x =
{  
  _others = 
  {
    foobar = "44k",
    snafu  = true,  -- or any place holder, I'm not fussy
  },
  lr = "lr",
  xafi = "444",
  method = "post",
  ttl = "55",
  userp = "blah",
  maddr = "help",
  transport = "http",
}

  But I've yet to come up with a simple solution.  I do have a solution for
parsing email headers [1] that works, but I don't care for it much (it
generates additional garbage, and for the problem I'm trying to solve now,
I'd like to avoid generating as much garbage as possible.

  It doesn't have to use re, it can be in straight lpeg.  I just want a way
to pull in a field name, and set that field in a table, all using LPeg,
ideally without external variables [2].  Oh, and there is no defined order
to the fields---they can come in any order (and for this problem, assume no
duplicates).

  Any ideas?

  -spc (Even an LPeg extention to get the current table being used to store
	captures?)

[1]	https://github.com/spc476/LPeg-Parsers/blob/master/email.lua