Discussion:
[ragel-users] What is a good pattern for reentering parser and limiting repetitions?
Daniel Janzon
2012-05-01 21:07:00 UTC
Permalink
Hi Guys,

I'd like to write a parser that can advance a little bit at a time as
input becomes available, with no need to look back. I came up
with the code below to test that. It's just a machine that must
read at least on 'a' and then at least one 'b'. Does it look like a
good pattern for this? I just save cs and set it againt when I come
back the next time. I guess the "nocs" option is not needed,
but does no harm either.

I also wonder what's a good way to limit repetitions. In the code
below, the buffer "result" could be overflowed. Either I build it
into the machine somehow (how?) or I need to check the buffer
limit for each byte in the action. I assume there must be a
standard way to do it but I couldn't find anything useful in the
manual.

All the best,
Daniel Janzon


#include <stdio.h>
#include <string.h>

%%{
machine testreenter;
write data;
}%%

struct parser
{
char result[1024];
int offset;
int state;
};

int parse(char *str, int len, struct parser *parser)
{
char *p=str, *pe=str+len;
int cs;

%%{
action character { parser->result[parser->offset++] = *fpc; }
main := (('a'+ 'b'+) $character);
write init nocs;
}%%

cs = parser->state;

%%{
write exec;
}%%
parser->state = cs;
}

int main()
{
char str1[] = "aaa";
char str2[] = "bbb";
struct parser parser;
memset(&parser, 0, sizeof(struct parser));
parser.state = testreenter_start;

parse(str1, strlen(str1), &parser);
parse(str2, strlen(str2), &parser);

printf("result is '%s'\n", parser.result);
}

Loading...