在C#/ .Net中解析Lua数据结构的最简单方法

时间:2022-06-01 21:31:17

Anyone know of an easy way to parse a Lua datastructure in C# or with any .Net library? This would be similar to JSON decoding, except for Lua instead of javascript.

有人知道在C#或任何.Net库中解析Lua数据结构的简单方法吗?这与JSON解码类似,除了Lua而不是javascript。

At this point it looks like I'll need to write my own, but hoping there's something already out there.

在这一点上看起来我需要自己编写,但希望已经有了一些东西。

5 个解决方案

#1


What Alexander said. The lab is the home of Lua, after all.

亚历山大说的话。毕竟,实验室是Lua的家。

Specifically, LuaInterface can allow a Lua interpreter to be embedded in your application so that you can use Lua's own parser to read the data. This is analogous to embedding Lua in a C/C++ application for use as a config/datafile language. The LuaCLR project might be fruitful at some point as well, but it may not be quite as mature.

具体来说,LuaInterface可以允许Lua解释器嵌入到您的应用程序中,以便您可以使用Lua自己的解析器来读取数据。这类似于将Lua嵌入C / C ++应用程序中以用作配置/数据文件语言。 LuaCLR项目在某些方面也可能富有成效,但可能不会那么成熟。

#2


Thanks to both of you, I found what I was looking for using LuaInterface

感谢你们两位,我用LuaInterface找到了我想要的东西

Here's a datastructure in Lua I wanted to read ("c:\sample.lua"):

这是Lua想要阅读的数据结构(“c:\ sample.lua”):

TestValues = {
    NumbericOneMillionth = 1e-006,
    NumbericOnehalf = 0.5,
    NumbericOne = 1,
    AString = "a string"
}

Here's some sample code reading that Lua datastructure using LuaInterface:

这是使用LuaInterface读取Lua数据结构的示例代码:

Lua lua = new Lua();

var result = lua.DoFile("C:\\sample.lua");

foreach (DictionaryEntry member in lua.GetTable("TestValues")) {
    Console.WriteLine("({0}) {1} = {2}", 
        member.Value.GetType().ToString(), 
        member.Key, 
        member.Value);
}

And here's what that sample code writes to the console:

以下是示例代码写入控制台的内容:

(System.String) AString = a string
(System.Double) NumbericOneMillionth = 1E-06
(System.Double) NumbericOnehalf = 0.5
(System.Double) NumbericOne = 1

To figure out how to use the library I opened up the LuaInterface.dll in Reflector and google'd the member functions.

为了弄清楚如何使用库,我在Reflector中打开了LuaInterface.dll,并对成员函数进行了google。

#3


LsonLib can parse Lua data structures, manipulate them and serialize the result back to Lua text. Full disclosure: I am the author. It's pure C# and has no dependencies.

LsonLib可以解析Lua数据结构,操纵它们并将结果序列化回Lua文本。完全披露:我是作者。它是纯粹的C#并且没有依赖关系。

Given:

MY_VAR = { "Foo", ["Bar"] = "Baz" }
ANOTHER = { 235, nil }

Basic usage:

var d = LsonVars.Parse(File.ReadAllText(somefile));

d["MY_VAR"][1].GetString()     // returns "Foo"
d["MY_VAR"]["Bar"].GetString() // returns "Baz"
d["MY_VAR"][2]                 // throws

d["ANOTHER"][1].GetString()    // throws because it's an int
d["ANOTHER"][1].GetInt()       // returns 235
d["ANOTHER"][2]                // returns null
d["ANOTHER"][1].GetStringLenient() // returns "235"

d["ANOTHER"][1] = "blah";      // now { "blah", nil }
d["ANOTHER"].Remove(2);        // now { "blah" }

File.WriteAllText(somefile, LsonVars.ToString(d)); // save changes

(it's actually a fairly straightforward port of a JSON library we use internally, hence it has quite a few features and might have some JSON traces left over)

(它实际上是我们在内部使用的JSON库的一个相当简单的端口,因此它具有相当多的功能并且可能留下一些JSON痕迹)

#4


You may (or may not) find what you need among Lablua projects.

您可能(或可能不)在Lablua项目中找到您需要的东西。

In any case, do not hesitate to ask your question on Lua mailing list.

无论如何,请不要犹豫,在L​​ua邮件列表上提问。

#5


I haven't looked at this one yet, saving a link for now: http://www.youpvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files.aspx

我还没有看过这个,现在保存一个链接:http://www.youpvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files。 ASPX

LuaInterface is unfortunately only packaged to run on x86, so I was looking at alternatives. Here's the source:

遗憾的是,LuaInterface只是打包在x86上运行,所以我在寻找其他选择。这是来源:

/*
 * Denis Bekman 2009
 * www.youpvp.com/blog
 --
 * This code is licensed under a Creative Commons Attribution 3.0 United States License.
 * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Net;

namespace YouPVP
{
    public class LuaParse
    {
        List<string> toks = new List<string>();

        public string Id { get; set; }
        public LuaObject Val { get; set; }
        public void Parse(string s)
        {
            string qs = string.Format("({0}[^{0}]*{0})", "\"");
            string[] z = Regex.Split(s, qs + @"|(=)|(,)|(\[)|(\])|(\{)|(\})|(--[^\n\r]*)");

            foreach (string tok in z)
            {
                if (tok.Trim().Length != 0 && !tok.StartsWith("--"))
                {
                    toks.Add(tok.Trim());
                }
            }

            Assign();
        }
        protected void Assign()
        {
            if (!IsLiteral)
                throw new Exception("expect identifier");
            Id = GetToken();
            if (!IsToken("="))
                throw new Exception("expect '='");
            NextToken();
            Val = RVal();
        }
        protected LuaObject RVal()
        {
            if (IsToken("{"))
                return LuaObject();
            else if (IsString)
                return GetString();
            else if (IsNumber)
                return GetNumber();
            else if (IsFloat)
                return GetFloat();
            else
                throw new Exception("expecting '{', a string or a number");
        }
        protected LuaObject LuaObject()
        {
            Dictionary<string, LuaObject> table = new Dictionary<string, LuaObject>();
            NextToken();
            while (!IsToken("}"))
            {
                if (IsToken("["))
                {
                    NextToken();
                    string name = GetString();
                    if (!IsToken("]"))
                        throw new Exception("expecting ']'");
                    NextToken();
                    if (!IsToken("="))
                        throw new Exception("expecting '='");
                    NextToken();
                    table.Add(name, RVal());
                }
                else
                {
                    table.Add(table.Count.ToString(), RVal());//array
                }
                if (!IsToken(","))
                    throw new Exception("expecting ','");
                NextToken();
            }
            NextToken();
            return table;
        }

        protected bool IsLiteral
        {
            get
            {
                return Regex.IsMatch(toks[0], "^[a-zA-Z]+[0-9a-zA-Z_]*");
            }
        }
        protected bool IsString
        {
            get
            {
                return Regex.IsMatch(toks[0], "^\"([^\"]*)\"");
            }
        }
        protected bool IsNumber
        {
            get
            {
                return Regex.IsMatch(toks[0], @"^\d+");
            }
        }
        protected bool IsFloat
        {
            get
            {
                return Regex.IsMatch(toks[0], @"^\d*\.\d+");
            }
        }
        protected string GetToken()
        {
            string v = toks[0];
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetString()
        {
            Match m = Regex.Match(toks[0], "^\"([^\"]*)\"");
            string v = m.Groups[1].Captures[0].Value;
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetNumber()
        {
            int v = Convert.ToInt32(toks[0]);
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetFloat()
        {
            double v = Convert.ToDouble(toks[0]);
            toks.RemoveAt(0);
            return v;
        }
        protected void NextToken()
        {
            toks.RemoveAt(0);
        }
        protected bool IsToken(string s)
        {
            return toks[0] == s;
        }
    }



    public class LuaObject : System.Collections.IEnumerable
    {
        private object luaobj;

        public LuaObject(object o)
        {
            luaobj = o;
        }
        public System.Collections.IEnumerator GetEnumerator()
        {
            Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
            return dic.GetEnumerator();
        }
        public LuaObject this[int ix]
        {
            get
            {
                Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
                try
                {
                    return dic[ix.ToString()];
                }
                catch (KeyNotFoundException)
                {
                    return null;
                }
            }
        }
        public LuaObject this[string index]
        {
            get
            {
                Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
                try
                {
                    return dic[index];
                }
                catch (KeyNotFoundException)
                {
                    return null;
                }
            }
        }
        public static implicit operator string(LuaObject m)
        {
            return m.luaobj as string;
        }
        public static implicit operator int(LuaObject m)
        {
            return (m.luaobj as int? ?? 0);
        }
        public static implicit operator LuaObject(string s)
        {
            return new LuaObject(s);
        }
        public static implicit operator LuaObject(int i)
        {
            return new LuaObject(i);
        }
        public static implicit operator LuaObject(double d)
        {
            return new LuaObject(d);
        }
        public static implicit operator LuaObject(Dictionary<string, LuaObject> dic)
        {
            return new LuaObject(dic);
        }
    }
}

#1


What Alexander said. The lab is the home of Lua, after all.

亚历山大说的话。毕竟,实验室是Lua的家。

Specifically, LuaInterface can allow a Lua interpreter to be embedded in your application so that you can use Lua's own parser to read the data. This is analogous to embedding Lua in a C/C++ application for use as a config/datafile language. The LuaCLR project might be fruitful at some point as well, but it may not be quite as mature.

具体来说,LuaInterface可以允许Lua解释器嵌入到您的应用程序中,以便您可以使用Lua自己的解析器来读取数据。这类似于将Lua嵌入C / C ++应用程序中以用作配置/数据文件语言。 LuaCLR项目在某些方面也可能富有成效,但可能不会那么成熟。

#2


Thanks to both of you, I found what I was looking for using LuaInterface

感谢你们两位,我用LuaInterface找到了我想要的东西

Here's a datastructure in Lua I wanted to read ("c:\sample.lua"):

这是Lua想要阅读的数据结构(“c:\ sample.lua”):

TestValues = {
    NumbericOneMillionth = 1e-006,
    NumbericOnehalf = 0.5,
    NumbericOne = 1,
    AString = "a string"
}

Here's some sample code reading that Lua datastructure using LuaInterface:

这是使用LuaInterface读取Lua数据结构的示例代码:

Lua lua = new Lua();

var result = lua.DoFile("C:\\sample.lua");

foreach (DictionaryEntry member in lua.GetTable("TestValues")) {
    Console.WriteLine("({0}) {1} = {2}", 
        member.Value.GetType().ToString(), 
        member.Key, 
        member.Value);
}

And here's what that sample code writes to the console:

以下是示例代码写入控制台的内容:

(System.String) AString = a string
(System.Double) NumbericOneMillionth = 1E-06
(System.Double) NumbericOnehalf = 0.5
(System.Double) NumbericOne = 1

To figure out how to use the library I opened up the LuaInterface.dll in Reflector and google'd the member functions.

为了弄清楚如何使用库,我在Reflector中打开了LuaInterface.dll,并对成员函数进行了google。

#3


LsonLib can parse Lua data structures, manipulate them and serialize the result back to Lua text. Full disclosure: I am the author. It's pure C# and has no dependencies.

LsonLib可以解析Lua数据结构,操纵它们并将结果序列化回Lua文本。完全披露:我是作者。它是纯粹的C#并且没有依赖关系。

Given:

MY_VAR = { "Foo", ["Bar"] = "Baz" }
ANOTHER = { 235, nil }

Basic usage:

var d = LsonVars.Parse(File.ReadAllText(somefile));

d["MY_VAR"][1].GetString()     // returns "Foo"
d["MY_VAR"]["Bar"].GetString() // returns "Baz"
d["MY_VAR"][2]                 // throws

d["ANOTHER"][1].GetString()    // throws because it's an int
d["ANOTHER"][1].GetInt()       // returns 235
d["ANOTHER"][2]                // returns null
d["ANOTHER"][1].GetStringLenient() // returns "235"

d["ANOTHER"][1] = "blah";      // now { "blah", nil }
d["ANOTHER"].Remove(2);        // now { "blah" }

File.WriteAllText(somefile, LsonVars.ToString(d)); // save changes

(it's actually a fairly straightforward port of a JSON library we use internally, hence it has quite a few features and might have some JSON traces left over)

(它实际上是我们在内部使用的JSON库的一个相当简单的端口,因此它具有相当多的功能并且可能留下一些JSON痕迹)

#4


You may (or may not) find what you need among Lablua projects.

您可能(或可能不)在Lablua项目中找到您需要的东西。

In any case, do not hesitate to ask your question on Lua mailing list.

无论如何,请不要犹豫,在L​​ua邮件列表上提问。

#5


I haven't looked at this one yet, saving a link for now: http://www.youpvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files.aspx

我还没有看过这个,现在保存一个链接:http://www.youpvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files。 ASPX

LuaInterface is unfortunately only packaged to run on x86, so I was looking at alternatives. Here's the source:

遗憾的是,LuaInterface只是打包在x86上运行,所以我在寻找其他选择。这是来源:

/*
 * Denis Bekman 2009
 * www.youpvp.com/blog
 --
 * This code is licensed under a Creative Commons Attribution 3.0 United States License.
 * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Net;

namespace YouPVP
{
    public class LuaParse
    {
        List<string> toks = new List<string>();

        public string Id { get; set; }
        public LuaObject Val { get; set; }
        public void Parse(string s)
        {
            string qs = string.Format("({0}[^{0}]*{0})", "\"");
            string[] z = Regex.Split(s, qs + @"|(=)|(,)|(\[)|(\])|(\{)|(\})|(--[^\n\r]*)");

            foreach (string tok in z)
            {
                if (tok.Trim().Length != 0 && !tok.StartsWith("--"))
                {
                    toks.Add(tok.Trim());
                }
            }

            Assign();
        }
        protected void Assign()
        {
            if (!IsLiteral)
                throw new Exception("expect identifier");
            Id = GetToken();
            if (!IsToken("="))
                throw new Exception("expect '='");
            NextToken();
            Val = RVal();
        }
        protected LuaObject RVal()
        {
            if (IsToken("{"))
                return LuaObject();
            else if (IsString)
                return GetString();
            else if (IsNumber)
                return GetNumber();
            else if (IsFloat)
                return GetFloat();
            else
                throw new Exception("expecting '{', a string or a number");
        }
        protected LuaObject LuaObject()
        {
            Dictionary<string, LuaObject> table = new Dictionary<string, LuaObject>();
            NextToken();
            while (!IsToken("}"))
            {
                if (IsToken("["))
                {
                    NextToken();
                    string name = GetString();
                    if (!IsToken("]"))
                        throw new Exception("expecting ']'");
                    NextToken();
                    if (!IsToken("="))
                        throw new Exception("expecting '='");
                    NextToken();
                    table.Add(name, RVal());
                }
                else
                {
                    table.Add(table.Count.ToString(), RVal());//array
                }
                if (!IsToken(","))
                    throw new Exception("expecting ','");
                NextToken();
            }
            NextToken();
            return table;
        }

        protected bool IsLiteral
        {
            get
            {
                return Regex.IsMatch(toks[0], "^[a-zA-Z]+[0-9a-zA-Z_]*");
            }
        }
        protected bool IsString
        {
            get
            {
                return Regex.IsMatch(toks[0], "^\"([^\"]*)\"");
            }
        }
        protected bool IsNumber
        {
            get
            {
                return Regex.IsMatch(toks[0], @"^\d+");
            }
        }
        protected bool IsFloat
        {
            get
            {
                return Regex.IsMatch(toks[0], @"^\d*\.\d+");
            }
        }
        protected string GetToken()
        {
            string v = toks[0];
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetString()
        {
            Match m = Regex.Match(toks[0], "^\"([^\"]*)\"");
            string v = m.Groups[1].Captures[0].Value;
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetNumber()
        {
            int v = Convert.ToInt32(toks[0]);
            toks.RemoveAt(0);
            return v;
        }
        protected LuaObject GetFloat()
        {
            double v = Convert.ToDouble(toks[0]);
            toks.RemoveAt(0);
            return v;
        }
        protected void NextToken()
        {
            toks.RemoveAt(0);
        }
        protected bool IsToken(string s)
        {
            return toks[0] == s;
        }
    }



    public class LuaObject : System.Collections.IEnumerable
    {
        private object luaobj;

        public LuaObject(object o)
        {
            luaobj = o;
        }
        public System.Collections.IEnumerator GetEnumerator()
        {
            Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
            return dic.GetEnumerator();
        }
        public LuaObject this[int ix]
        {
            get
            {
                Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
                try
                {
                    return dic[ix.ToString()];
                }
                catch (KeyNotFoundException)
                {
                    return null;
                }
            }
        }
        public LuaObject this[string index]
        {
            get
            {
                Dictionary<string, LuaObject> dic = luaobj as Dictionary<string, LuaObject>;
                try
                {
                    return dic[index];
                }
                catch (KeyNotFoundException)
                {
                    return null;
                }
            }
        }
        public static implicit operator string(LuaObject m)
        {
            return m.luaobj as string;
        }
        public static implicit operator int(LuaObject m)
        {
            return (m.luaobj as int? ?? 0);
        }
        public static implicit operator LuaObject(string s)
        {
            return new LuaObject(s);
        }
        public static implicit operator LuaObject(int i)
        {
            return new LuaObject(i);
        }
        public static implicit operator LuaObject(double d)
        {
            return new LuaObject(d);
        }
        public static implicit operator LuaObject(Dictionary<string, LuaObject> dic)
        {
            return new LuaObject(dic);
        }
    }
}