Daniel Janzon
2012-05-01 21:07:00 UTC
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);
}
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);
}