pdimitar pdimitar - 1 month ago 24
Java Question

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. ;)

Answer

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"}}}