Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I need a tool to parse Lua tables, preferrably in Ruby or Java

I need a tool to parse Lua table expressions. If all else fails, I will eventually just code a small Lua module to convert tables to XML, but for the time being, I am interested in a Ruby library doing that, but failing that, I would accept tool in any language, provided I can look at its source.

Here is an example snippet (it's a WoW addon output):

CT_RaidTracker_RaidLog = {
{
    ["PlayerInfos"] = {
        ["Nyim"] = {
            ["race"] = "Orc",
            ["guild"] = "Excubitores Noctae",
            ["sex"] = 2,
            ["class"] = "HUNTER",
            ["level"] = 70,
        },
        ["Zyrn"] = {
            ["race"] = "BloodElf",
            ["guild"] = "Excubitores Noctae",
            ["sex"] = 2,
            ["class"] = "WARLOCK",
            ["level"] = 70,
        },
...

Basic idea is, nested associative arrays. Any help or pointer will be examined, any idea is appreciated.

EDIT #1

Due to the disputes, let me clarify what did I try. I complemented the string/regex replacing chain provided by one of the participants, like so:

str.gsub(/--.+$/, "").gsub("=", ":").gsub(/[\[\]]/,"").gsub('" :','":').gsub(/,\s*\n(\s*)}/, "\n\\1}")

I (1) added removal of Lua comments, (2) replaced one of the regex replacers: when you have the last element in an object/array, it still has a comma after it, so that must be covered and the comma properly removed.

Do you notice the double opening curly braces? JSON doesn't like having anonymous objects. It looks like that:

"xxx" = {
  {
    ["aaa"} = {
      ["bbb"] = {
        "ccc" = 7
        "ddd" = "a string"
        "eee" = "a date/time pattern"
      }
    },
    ["qqq"} = {
      "hm" = "something"
    }
  },
  {
    ["aaa"] = {
    -- ...
    },
    ["qqq"] = {
    -- ...
    }
  }
}

Basically on the root level, we actually have a list/array of similar objects, both having "aaa" and "qqq" section, to follow the example. However, in Lua that is obviously allowed, while in JSON it isn't. Because the opening curly braces are treated like "start an object" but that object doesn't have a name.

I tried to detect that case with regex and replace curly braces with "[]" pairs. While the resulting regex worked, the problem was the same: OK, we define an array of similar objects instead, but the declaration of the array is still nameless.

A possible solution would be instead of detecting and replacing those braces with [], to christen the objects with indexes, like: "0" = { "aaa" = {...} }, "1" = { "aaa" = {... } }, etc. That (hopefully final) workaround will probably make it work... Will report back again. ;)

like image 962
dimitarvp Avatar asked Dec 03 '22 06:12

dimitarvp


2 Answers

I'm probably stating the obvious, but Lua can certainly parse Lua tables. And you can "embed" Lua in pretty much any mainstream language including Java and Ruby (scroll down the link for Java and Ruby bindings). By embed, I mean parsing source files, calling Lua functions and exploring tables, may be even calling functions written in your host language from Lua. It's possible that these binding libraries are more work than exporting your tables to XML/JSON, but it's worth looking at them at least

Edit: level 70? That's so last decade ;)

like image 59
sbk Avatar answered Dec 06 '22 10:12

sbk


Skipping the first line and then some ad hoc transformation to JSON.

s=File.readlines("test.luatable")[1..-1].join
JSON.parse(s.gsub("=", ":").gsub(/[\[\]]/,"").gsub('" :','":').gsub(/,\n(.+)\}/,"\n\\1}"))
=> {"PlayerInfos"=>{"Nyim"=>{"guild"=>"Excubitores Noctae", "class"=>"HUNTER",  
    "level"=>70, "sex"=>2, "race"=>"Orc"}, "Zyrn"=>{"guild"=>"Excubitores Noctae", 
    "class"=>"WARLOCK", "level"=>70, "sex"=>2, "race"=>"BloodElf"}}}
like image 26
Jonas Elfström Avatar answered Dec 06 '22 11:12

Jonas Elfström