[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Best way to set a lua table from a parser written in C
- From: HyperHacker <hyperhacker@...>
- Date: Thu, 28 Oct 2010 13:53:53 -0600
On Thu, Oct 28, 2010 at 13:35, Luiz Henrique de Figueiredo
<lhf@tecgraf.puc-rio.br> wrote:
>> 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
>
> Have a look at my lcl: http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lcl
>
> It'll turn these lines into the equivalent of
> square("square_name","-x","20","-y","30","-height","20","-width","50")
> circle("circle_name","-x","50","-y","60","-radius","100")
> except that there is not textual transformation: the evaluation is done
> on the fly.
>
>
This looks like something you could parse fairly trivially into Lua
code like [[ square "square_name" {x=20, y=30...} ]], and then pass to
luaL_dostring(). (This is valid syntax as long as square() returns
another function for the table to be passed to). Just watch for the
possibility of an injection attack if anyone is still creating files
in this format.
If it's simpler to read, you might even keep the names as-is and wrap
them in [""]: {["-width"] = 50}. The Lua code can then transform the
table as needed. By this point the C-side parsing is fairly simple:
char input[1024], *str[32];
/* ... read a line into input however you like... */
int idx=1, i=-1;
str[0] = input;
while((input[++i] != '\0') && (idx<32)) { /* not end of string and str
not full */
if(input[i] == ' ') { /* split at space */
input[i] = '\0';
str[idx++] = &input[i+1]; /* add next string to str */
}
}
idx--; /* last entry would point to an empty/undefined string */
printf("%s \"%s\" {\n, str[0], str[1]);
for(int i=2; i<idx; i += 2) printf("[\"%s\"] = %s,\n", str[i], str[i+1]);
printf("}\n")
(Obviously a bit hacky, lacking some sanity checks, but gets the idea
across.) You'd get nice code like:
square "square_name" {
["-x"] = 20,
["-y"] = 50,
--[[...more fields...]],
}
and then you use some Lua code to make functions like square() work
and change the field names to something more useful.
--
Sent from my toaster.