在 C#/.Net 中解析 Lua 数据结构的最简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/881445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Easiest way to parse a Lua datastructure in C# / .Net
提问by Frank Schwieterman
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.
在这一点上,看起来我需要自己编写,但希望已经有一些东西了。
采纳答案by RBerteig
What Alexander said. The lab is the home of Lua, after all.
亚历山大说的。毕竟,实验室是 Lua 的家。
Specifically, LuaInterfacecan 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 LuaCLRproject might be fruitful at some point as well, but it may not be quite as mature.
具体来说,LuaInterface可以允许在您的应用程序中嵌入 Lua 解释器,以便您可以使用 Lua 自己的解析器来读取数据。这类似于在 C/C++ 应用程序中嵌入 Lua 以用作配置/数据文件语言。该LuaCLR项目可能会在某些时候卓有成效的为好,但它可能不是很成熟。
回答by Alexander Gladysh
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.
无论如何,请不要犹豫,在Lua 邮件列表上提出您的问题。
回答by Frank Schwieterman
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 并搜索了成员函数。
回答by Frank Schwieterman
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);
}
}
}
回答by Roman Starkov
LsonLibcan 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 痕迹)