Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse any constant Lua table preferably without loading it in the Lua VM?

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?

like image 335
lesderid Avatar asked Nov 04 '12 15:11

lesderid


2 Answers

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.

like image 142
jspcal Avatar answered Nov 11 '22 16:11

jspcal


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:

  • http://www.moonsharp.org
  • https://github.com/xanathar/moonsharp/

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:

  • http://www.moonsharp.org
  • https://github.com/xanathar/moonsharp/

I have started to write some extensions which have units test which show further usage in one of my repos (See links below)

Links:

  • https://github.com/dibley1973/MoonsharpExtensions
like image 41
Dib Avatar answered Nov 11 '22 14:11

Dib