أحتاج إلى أداة لتحليل جداول Lua، ويفضل أن تكون في Ruby أو Java

StackOverflow https://stackoverflow.com/questions/2370153

سؤال

أحتاج إلى أداة لتحليل تعبيرات جدول 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" = {... } }, ، إلخ.من المحتمل أن يؤدي هذا الحل البديل (المأمول النهائي) إلى نجاحه ...سوف يقدم تقريرا مرة أخرى.;)

هل كانت مفيدة؟

المحلول

تخطي الخط الأول ثم بعض التحول المخصص إلى 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"}}}

نصائح أخرى

ربما أذكر ما هو واضح ، لكن لوا يمكنه بالتأكيد تحليل طاولات لوا. ويمكنك "تضمين" لوا في أي لغة سائدة إلى حد كبير بما في ذلك Java و Ruby (قم بالتمرير لأسفل الرابط لربط Java و Ruby). بالتضمين ، أعني تحليل ملفات المصدر ، واتصال وظائف LUA واستكشاف الجداول ، حتى أن وظائف الاتصال المكتوبة بلغة المضيف الخاصة بك من LUA. من المحتمل أن تكون هذه المكتبات الملزمة أكثر من تصدير الجداول الخاصة بك إلى XML/JSON ، ولكن الأمر يستحق النظر إليها على الأقل

تحرير: المستوى 70؟ هذا هو العقد الماضي ؛)

من السهل كتابة برنامج LUA الذي يخرج الجداول في XML ولكنه يعتمد على كيفية تنسيق XML. أنظر أيضا luaxml, ، الذي يحتوي على XML.Save (ولكنه مكتوب في C) و هذا السؤال.

ربما سيكون أسهل في الاستخدام JSON من XML في هذه الحالة.

تكون الترجمة من جداول lua تقريبًا من 1 إلى 1 (التغيير = إلى: وإزالة [ و ] من المفاتيح).هذا هو ما يعادل 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).

لتتمكن من قراءتها من تطبيق روبي، عليك أن تفعل شيئًا مشابهًا لما يلي:

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

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

ثم ستكون معلومات اللاعب متاحة على:

player_infos = info["PlayerInfos"]

يوجد أيضًا محلل Java JSON، لكن ليس لدي خبرة به.

جرب هذا الرمز

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)

أذكر أنه يمكنك فقط استخدام 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();}
  ;

يولد محللًا يمكن أن يأخذ مدخلات مثل:

Table = {
  ["k1"] = "v1",
  ["k2"] = {["x"]=1, ["y"]=2},
  ["k3"] = "v3"
}

وتحويله إلى:

alt text http://img59.imageshack.us/img59/7112/treef.png

(انقر هنا للحصول على حل كامل للصورة)

كتابة XML من بنية الشجرة هذه هي مسرحية الطفل.

ولكن كما قلت ، يمكن أن تبدو طاولات لوا مختلفة تمامًا عن القواعد النحوية التي نشرتها أعلاه: يمكن أن تبدو السلاسل:

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

ويمكن أن تتكون المفاتيح والقيم من تعبيرات. ولكن إذا كانت الأشجار تبدو دائمًا مثل كيفية نشرها ، فقد يكون ذلك خيارًا لك.

حظا طيبا وفقك الله!

كنت بحاجة للقيام بذلك في جافا ، لذلك كتبت مكتبة صغيرة:

https://github.com/mutantbob/jluadata

رمز لم يخبر. وأنا فقط أتابع رابط SBK هنا ، لذلك لا أستحق أي رصيد على الإطلاق.

require 'rubyluabridge'

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

هل يمكنني الإشارة إلى أن لوا ليس لديه قدرات regex ، فقط استبدال النص المتطابق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top