lua-users home
lua-l archive

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


Sean Conner's incomplete solution uses lpeg.Carg(1) which doesn't work recursively.

This is what I'm trying to parse: https://github.com/SoniEx2/MDXML

This is what I currently have:

----------------------------------
  --[[
    EOF/newlines/whitespace/inline comments
  --]]
  local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat

  local ws = lpeg.S(" \t") + nl - nl * nl
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`\n"))) ^ 0 * lpeg.P("`")
  local wsc = ws + inlineComment -- comments count as whitespace

  --[[
    Escape sequences
  --]]

  local backslashEscaped
  = lpeg.P("\\ ") / " " -- escaped spaces
  + lpeg.P("\\\\") / "\\" -- escaped escape character
  + lpeg.P("\\#") / "#"
  + lpeg.P("\\>") / ">"
  + lpeg.P("\\`") / "`"
  + lpeg.P("\\n") -- \\n newlines count as backslash escaped
  + lpeg.P("\\") * lpeg.P(function(_, i)
      error("Unknown backslash escape at position " .. i)
    end)

local content = lpeg.Cs((wsc / " " + (backslashEscaped + 1 - nl*nl))^0) * nl * nl

  --[[
    Process tag/attribute/value/etc
    (the `c` in the argument names means "captured")
  --]]

  local tag = lpeg.P"#" * lpeg.C((1 - nl)^1) * nl / function(ctag)
    return content:match(ctag)
  end

local attribute = lpeg.P"##" * lpeg.C((1 - nl)^1) * nl / function(cattribute)
    return content:match(cattribute)
  end

  local value = lpeg.P"###" * lpeg.C((1 - nl)^1) * nl / function(cvalue)
    return content:match(cvalue)
  end

  local tagns = lpeg.P"####" * lpeg.C((1 - nl)^1) * nl / function(ctagns)
    return content:match(ctagns)
  end

local attrns = lpeg.P"#####" * lpeg.C((1 - nl)^1) * nl / function(cattrns)
    return content:match(cattrns)
  end

  --[[
    Recursive grammar.
  --]]

  local doc = lpeg.P { lpeg.V"entry",
    entry = ((lpeg.Carg(1) * lpeg.C(tag))
    / function(t,tag)
      local x = { [0] = tag }
      table.insert(t,x)
      return t
    end
    * (
      (lpeg.Carg(1) * lpeg.C(tagns))
      / function (t, ns)
        local x = t[#t]
        local tag = x[0]
        x[0] = {tag=tag, ns=ns}
      end
      )^0
    * (
      (lpeg.Carg(1) * lpeg.C(attribute) * lpeg.C(value))
      /  function(t,a,v)
        local x = t[#t]
        x[a] = v
        return t
      end
      )^0
    * (
      (lpeg.Carg(1) * lpeg.C(content))
      /  function(t,c)
        local x = t[#t]
        table.insert(x,c)
        return t
      end
      )^0)
  }
----------------------------------

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.