On 11/10/2012 12:59 PM, Karel Sedláček wrote:
Thanks, but could you maybe give me a 10-liner that exemplifies this
kind of behavior inside another application? Let's say I have my own
event loop set up to feed Ragel buffers. Where do I (or does Ragel)
allocate and store it's state? How do I get the pair of functions
described above that are parameterized over the state and consume
incremental new input? Can I have Ragel pass me a bit of userdata as
well, where I can keep the parse state and the thing receiving the
events? Keeping it simple, how about a parser that has an in-action
that tells a C function got_null(void *userdata, size_t start_addr)
whenever it encounters a 0 byte. Prototypes below:
void got_null(void *userdata, size_t start_addr);
int parse_null(ragel_state_t *st, void *buf, size_t buf_len, void *userdata);
int parse_null_eof(rage_state_t *st, void *userdata);
Well, maybe not a 10-liner, but I think I have a single function that
might make it clear.
Ragel generates code that uses special named variables. You can either
map these to code (as I did with 'stack' and 'eof') or use local
variables (like with 'p' and 'pe'). Or, mix and match. You get to
persist them however you like.
As you can see, ragel's engine (as I'm using it) is nothing more than a
generated while loop state machine. The state is entirely stored in the
variables [p, pe, cs] and I give it an rvalue for 'eof'. I'm also using
the [stack, top] for recursion ability. You can preserve these state
variables however you like.
bool wiki_scanner_scanMore(wiki_scanner_t *scanner) {
const char
*p= scanner->curPos,
*pe= scanner->bufferLimit;
int cs= scanner->curState;
log_pos(start); //macro that prints trace info for debugging
%%{
variable stack scanner->stateStack;
variable top scanner->stateStackPos;
variable eof (scanner->eof? pe : NULL);
prepush {
if (scanner->stateStackPos >= scanner->stateStackLen) {
if (!scanner_enlarge_stateStack(scanner)) {
fprintf(stderr, "ltw_scanner: recursion limit: %d
levels deep; scan may emit incorrect results.\n", scanner->stateStackPos);
scanner->stateStackPos--;
}
}
}
write exec;
}%%
assert(p == pe);
scanner->curPos= p;
scanner->curState= cs;
return true;
}
Hope that helps.
-Mike
_______________________________________________
ragel-users mailing list
ragel-users@complang.org
http://www.complang.org/mailman/listinfo/ragel-users