我正在考虑使用Ragel为嵌入式系统中的NMEA GPS数据生成词法分析器。我会有一个任意大小的缓冲区,我从UART中读取数据块,对于每次读取,我都会将这些数据传递给词法分析器。
我希望能够提取特定字段,但问题是我无法保证数据块中存在整个字段。任何字段都可能被分割为两个读取,因此设置指向字段开头和结尾的指针可能会使开始指针位于前一个(现在被覆盖的)缓冲区的末尾,而结束指针则位于它之前。
一个让人想到的解决方案是在每个字段上使用'$'操作将字符逐个推送到另一个内存位(可能是struct字段)。这是最好的方法吗?
答案 0 :(得分:3)
为了它的价值,我最终得到了这个:
%%{
machine nmea;
action store { *wptr = fc; }
action append { *wptr++ = fc; }
action term { *wptr++ = 0; }
integer = digit+;
float = digit+ '.' digit+;
rmc = '$GPRMC,'
float ','
[AV] >{ wptr = &loc.valid; } $store ','
float? >{ wptr = loc.lat; } $append %term ','
[NS]? >{ wptr = &loc.ns; } $store ','
float? >{ wptr = loc.lng; } $append %term ','
[EW]? >{ wptr = &loc.ew; } $store
print*
'\n' >{ printf("%c, %s, %c, %s, %c\n", loc.valid, loc.lat, loc.ns, loc.lng, loc.ew); }
;
main := any* rmc;
}%%
答案 1 :(得分:0)
您可能希望为代码添加溢出保护,以避免恶意或其他错误输入的未定义行为:
char buf[1024], *wptr = buf, *wmax = buf + sizeof(buf) - 2;
action append { if (wptr < wmax) *wptr++ = fc; }