Мне нужен инструмент для разбора таблиц Lua, желательно в Ruby или Java - PullRequest
4 голосов
/ 03 марта 2010

Мне нужен инструмент для разбора табличных выражений Lua. Если все остальное не сработает, я в конечном итоге просто кодирую небольшой модуль Lua для преобразования таблиц в XML, но на данный момент меня интересует библиотека Ruby, которая делает это, но в случае неудачи я принимаю инструмент на любом языке, если я можно посмотреть на его источник.

Вот пример фрагмента (вывод дополнения WoW):

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,
        },
...

Основная идея - вложенные ассоциативные массивы. Любая помощь или указатель будут рассмотрены, любая идея приветствуется.

EDIT #1

В связи со спорами позвольте мне уточнить, что я пытался. Я дополнил цепочку замены строк / регулярных выражений, предоставленную одним из участников, примерно так:

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

Я (1) добавил удаление комментариев Lua, (2) заменил один из заменителей регулярных выражений: когда у вас есть последний элемент в объекте / массиве, после него все еще стоит запятая, так что это должно быть закрыто и запятая правильно удалена.

Вы заметили фигурные скобки с двойным открытием ? JSON не нравится иметь анонимные объекты. Это выглядит так:

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

В основном на корневом уровне у нас фактически есть список / массив похожих объектов, оба из которых имеют разделы "aaa" и "qqq", чтобы следовать примеру. Однако в Lua это явно разрешено, а в JSON - нет. Поскольку открывающиеся фигурные скобки обрабатываются как «начать объект», но у этого объекта нет имени.

Я попытался обнаружить этот случай с помощью регулярного выражения и заменить фигурные скобки на пары "[]". В то время как полученное регулярное выражение работало, проблема была та же: хорошо, мы вместо этого определяем массив похожих объектов, но объявление массива все еще безымянно.

Возможным решением было бы вместо обнаружения и замены этих фигурных скобок [], чтобы окрестить объекты индексами, например: "0" = { "aaa" = {...} }, "1" = { "aaa" = {... } } и т. Д. Этот (надеюсь окончательный) обходной путь, вероятно, заставит его работать ... Будет сообщать вернуться снова. ;)

Ответы [ 9 ]

5 голосов
/ 03 марта 2010

Я, вероятно, констатирую очевидное, но Lua, безусловно, может анализировать таблицы Lua. И вы можете "встраивать" Lua практически в любой основной язык , включая Java и Ruby (прокрутите вниз ссылку для привязки Java и Ruby). Под встраиванием я имею в виду, что синтаксический анализ исходных файлов, вызов функций Lua и исследование таблиц могут даже вызывать функции, написанные на языке вашего хоста из Lua. Возможно, что эти библиотеки связывания более эффективны, чем экспорт таблиц в XML / JSON, но стоит взглянуть на них как минимум

Редактировать: уровень 70? Это так в последнее десятилетие;)

3 голосов
/ 03 марта 2010

Пропуск первой строки, а затем некоторое специальное преобразование в 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"}}}
3 голосов
/ 03 марта 2010

Возможно, в этом случае будет проще использовать JSON , чем xml.

Перевод из таблиц lua почти один к одному (измените = на: и удалите [и] из ключей). Это эквивалент JSON вашего примера:

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

...

Кроме того, в Rails есть встроенный JSON-анализ (через JSON :: parse).

Чтобы прочитать его из приложения ruby, вам нужно сделать что-то похожее на это:

require 'json' # This is already included on Rails apps

info = JSON::parse(File.read("PlayerInfos.json"))

Тогда информация об игроке будет доступна по адресу:

player_infos = info["PlayerInfos"]

Есть также java-анализатор JSON, но у меня нет опыта работы с ним.

3 голосов
/ 03 марта 2010

Просто написать программу на Lua, которая выводит таблицы в XML, но это зависит от того, как вы хотите отформатировать XML. См. Также LuaXML , который имеет xml.save (но написан на C) и этот вопрос .

2 голосов
/ 04 марта 2010

Попробуйте этот код

function toxml(t,n)
        local s=string.rep(" ",n)
        for k,v in pairs(t) do
                print(s.."<"..k..">")
                if type(v)=="table" then
                        toxml(v,n+1)
                else
                        print(s.." "..v)
                end
                print(s.."</"..k..">")
        end
end

toxml(CT_RaidTracker_RaidLog,0)
1 голос
/ 27 марта 2013

Мне нужно было сделать это на Java, поэтому я написал небольшую библиотеку:

https://github.com/mutantbob/jluadata

1 голос
/ 03 марта 2010

Вы упоминаете, что можете использовать только Java, Ruby или PHP для этого.Можно использовать такой инструмент, как ANTLR, чтобы сгенерировать для вас небольшой синтаксический анализатор.

Грамматика ANTLR:

grammar Test;

parse
  :  Identifier '=' table EOF
  ;

table
  :  '{' (entry (',' entry)* ','?)? '}'
  ;

entry
  :  key ('=' value)?
  |  String
  |  Number
  ;

key
  :  '[' (String | Number) ']'
  |  Identifier
  ;

value
  :  String 
  |  Number
  |  Identifier
  |  table
  ;

Identifier
  :  ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*
  ;

String
  :  '"' ~'"'* '"'
  ;

Number
  :  '0'..'9'+
  ;

Space
  :  (' ' | '\t' | '\r' | '\n') {skip();}
  ;

генерирует синтаксический анализатор, который может принимать следующие данные:*

и преобразуйте его в:

альтернативный текст http://img59.imageshack.us/img59/7112/treef.png

(нажмите здесь для полного разрешения изображения)

ЗаписьXML из этой древовидной структуры - детская игра.

Но, как я уже сказал, таблицы Lua могут сильно отличаться от грамматики, которую я разместил выше: строки могут выглядеть так:

'a string'
[===[ also ]==] a string ]===]

и ключии значения могут состоять из выражений.Но если деревья всегда выглядят так, как вы их разместили, это может быть вариантом для вас.

Удачи!

0 голосов
/ 04 марта 2010

Могу ли я указать, что у Lua нет возможностей регулярных выражений, только замена текста по шаблону.

0 голосов
/ 03 марта 2010

непроверенный код. И я просто перехожу по ссылке Sbk здесь, так что я не заслуживаю никакого доверия.

require 'rubyluabridge'

def lua_data_to_ruby_hash(data)
    luastate = Lua::State.new
    luastate.eval "d = #{data}"
    return luastate.d.to_hash
end
...