lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Here is an example of how I transform a YAJL event parser stream into
lua tables and such:

http://github.com/brimworks/lua-yajl/blob/f566e81c77b91a65c791f7b8bab4313c93f85900/lua_yajl.c#L221

IMHO, event parsers are the most flexible of parsers since they can
operate on streams in event loops, although it is tricky to get
Yacc/Lex to generate these sort of parsers.  My personal favorite tool
for parser generation at the moment is Ragel, I wrote an HTML5 parser
for work using Ragel, and the grammar is reasonably easy to
understand.

Anyways, my YAJL binding works by registering a set of callbacks (in
the js_to_value_callbacks static variable) which the YAJL parser calls
when it finds things.  I then use the Lua stack to push a "combining
function" which is initially a "no op".

The YAJL parser will then call one of the registered callbacks, for
example to_value_start_map() which pushes a table on the Lua stack,
allocates space for the "current key", pushes the new "combining
function" which is got_map_key.

Next, to_value_string() callback should be triggered which pushes a
string on the Lua stack and executes the "combining funtion" which in
this case is got_map_key() which set the "current key" which was
previously a nil placeholder, then replaces the top of the stack with
the new "combining function" got_map_value().

Next, if the JSON input is a number then to_value_number() gets called
and does the exact same thing as to_value_string(): push the number on
the top of the lua stack and call the "combining function" which in
this case is get_map_value().  The get_map_value() function simply
sets the key and value on the table, removing the get_map_value()
function from the Lua stack, then allocates space for the "current
key" and pushes the got_map_key "combining function".

Now, if the JSON input terminates the table then to_value_end() gets
called which removes the space allocated for the "current key" and
removes the "combining function".  It then calls the previous
"combining function" (which is noop in this case).

The final result is a table at the top of the stack which contains the
key and value.

Anyways, hopefully this helps you get an idea of how easy the Lua API is :-).

Cheers,
-Brian

On Thu, Oct 28, 2010 at 11:52 AM, Silas Silva <silasdb@gmail.com> wrote:
> Hello all,
>
> I'm writting a parser in C (Lex & Yacc), to process a DSL similar to
> that:
>
>    square square_name -x 20 -y 30 -height 20 -width 50
>    circle circle_name -x 50 -y 60 -radius 100
>
> After parsing this, I need to set a table with information about these
> "objects" and pass it to a Lua script, so it can do anything with that
> information, like drawing that on the screen.
>
> My question is, from the parse level (a Yacc - .y - file) what is the
> best way, conceptually, to pass it to Lua using a table?
>
> I first thought about storing information in C structures, having a list
> of them and after everything is stored, convert those structures to Lua
> tables that can be used in a Lua script.
>
> But after talking to a friend of mine (Eduardo Ochs -
> http://angg.twu.net/), I realized that I could simply put parsed
> information in Lua tables using the Lua API (it is possible, right),
> just after I got the token, yet at the .y file.  That would avoid the
> hassle (or the fun?) of dealing with C code as early as possible.
>
> What solution do you propose for this simple problem?
>
> Thanks!
>
> --
> Silas Silva
>
>



-- 
Brian Maher >> Glory to God <<