C# または任意の .Net ライブラリで Lua データ構造を解析する簡単な方法を知っている人はいますか? これは、JavaScript の代わりに Lua を使用することを除いて、JSON デコードに似ています。
この時点で、私は自分で書く必要があるように見えますが、すでにそこに何かがあることを願っています.
お二人のおかげで、LuaInterface を使用して探していたものが見つかりました
読みたかった Lua のデータ構造は次のとおりです ("c:\sample.lua"):
TestValues = {
NumbericOneMillionth = 1e-006,
NumbericOnehalf = 0.5,
NumbericOne = 1,
AString = "a string"
}
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);
}
そして、そのサンプル コードがコンソールに書き込む内容は次のとおりです。
(System.String) AString = a string
(System.Double) NumbericOneMillionth = 1E-06
(System.Double) NumbericOnehalf = 0.5
(System.Double) NumbericOne = 1
ライブラリの使用方法を理解するために、Reflector で LuaInterface.dll を開き、メンバー関数をググってみました。
LsonLibは、Lua データ構造を解析して操作し、結果をシリアル化して Lua テキストに戻すことができます。完全な開示:私は著者です。これは純粋な C# であり、依存関係はありません。
与えられた:
MY_VAR = { "Foo", ["Bar"] = "Baz" }
ANOTHER = { 235, nil }
基本的な使い方:
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
(実際には、内部で使用する JSON ライブラリのかなり単純なポートであるため、かなりの数の機能があり、JSON トレースが残っている可能性があります)
アレクサンダーが言ったこと。研究室はルアの本拠地ですから。
具体的には、LuaInterfaceを使用すると、Lua インタープリターをアプリケーションに組み込むことができるため、Lua 独自のパーサーを使用してデータを読み取ることができます。これは、構成/データファイル言語として使用するために C/C++ アプリケーションに Lua を埋め込むことに似ています。LuaCLRプロジェクトも、ある時点で実りあるものになるかもしれませんが、それほど成熟していない可能性があります。
私はまだこれを見ていないので、今のところリンクを保存します: http://www.youupvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files. aspx
残念ながら、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);
}
}
}
Lablua プロジェクトの中から必要なものが見つかるかもしれません (見つからないかもしれません) 。
いずれにせよ、遠慮なくLua メーリング リストで質問してください。