I have a bunch of data in the form of a Lua table and I would like to parse that data into a usable structure in C#.
The problem with Lua tables is that there are optional fields, tables are very dynamic and are not just a dictionary with one type for the key and one type for the value. It's possible to have one Lua table with both string and integer keys, and values of type integer, string and even table.
Sadly, the data that I'm parsing makes use of the dynamic nature of the language and isn't really structured in any straight-forward way. This requires a dynamic representation of the data, using for example Dictionary<object, dynamic>
.
The format of the data is e.g. (from http://ideone.com/9nzXvt)
local mainNode =
{
[0] =
{
Name = "First element",
Comments = "I have comments!",
Data = { {123, 456}; foo = { "bar" } }
},
[1337] =
{
Name = "Another element",
Data = { {0}; foo = nil }
}
}
Are there any libraries out there to do this? Is there any way to accomplish this without parsing the data character by character?
You can use the luainterface library
There's some sample code here.
You'll want to use a combination of DoFile
(to load the file) and GetTable
to read the table into a LuaTable
object that you can use the result from c#. The LuaTable
exposes an IDictionaryEnumerator
through GetEnumerator
.
EDIT:
if you had this table constructor:
local t = { os.time() }
print(t[1]);
the function in the constructor would need to be executed to initialize the data.
for constant literals, you can have string constants like so:
local a = [==[
hello
there""\"]==]
with different levels of equal signs
a numeric literal can have the form:
0X1.921FB54442D18P+1
with P as a binary exponent.
faithfully reproducing the lua syntax for constant literals without using the lightweight lua VM would require re-implementing a good chunk of the lua language spec. not much benefit it re-inventing the wheel.
I know this is an old post, but this could be useful for people who arrive here after this post...
You could also look at Xanathar's MoonSharp (Moon#) project; I have just started to try it and it seems to work well with wrapping up the dynamic tables, with nested tables etc. You just give the interpreter a a script and it will parse and hold the parsed objects in the interpreter context.
Links:
Example:
[TestMethod]
public void Test_GetProperty_ForValidTypeAndKey_ReturnsValue()
{
// Arrange
String luaScript = MockLuaScripts.TEST_OBJECT_WITH_STRING;
Script context = new Script();
String expectedResult = MockLuaScripts.ValidValue1;
// Act
/* Run the script */
context.DoString(luaScript);
/* Get the object */
DynValue resultObject = context.Globals.Get(MockLuaScripts.ObjectInstance1);
/* Get the property */
DynValue tableValue = instance.Table.Get((MockLuaScripts.ValidKey1);
String actualResult = tableValue.String();
/* Or you can use..
String actualResult = tableValue.ToObject<String>();
*/
// Assert
Assert.AreEqual(expectedResult, actualResult);
}
Apologies if the above code is not exactly correct as it is taken from one of my test classes and converted for posting here. Please excuse the wrapped up mock-data constants, but they are in essence the Lua script and expected values.
When trying to access entries in Lua table via an incorrect key the DynValue has a DataType of "Nil", so are easy to handle with a conditional check.
More examples on usage of Xanathar's Moonsharp can be found on Xanathar's website and his git hub repo. (See links below). He seems to be very helpful with any issues or questions that you may come across too.
Links:
I have started to write some extensions which have units test which show further usage in one of my repos (See links below)
Links:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With