2

我正在考虑使用 Ragel 在嵌入式系统中为 NMEA GPS 数据生成词法分析器。我将有一个任意大小的缓冲区,我将从 UART 读取数据块,并且对于每次读取,我都会将该数据传递给词法分析器。

我希望能够提取特定字段,但问题是我不能保证整个字段都存在于数据块中。任何字段都可能被拆分为两次读取,因此将指针设置为字段的开始和结束可能会将开始指针留在前一个(现在被覆盖)缓冲区的末尾,而结束指针在它之前。

想到的一种解决方案是在每个字段上使用“$”操作,将字符一个接一个地推入另一位内存(可能是结构字段)。这是最好的方法吗?

4

2 回答 2

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;
}%%
于 2014-04-29T02:49:23.743 回答
0

您可能希望为代码添加溢出保护,以避免恶意或其他错误输入的未定义行为:

char buf[1024], *wptr = buf, *wmax = buf + sizeof(buf) - 2;

action append { if (wptr < wmax) *wptr++ = fc; }
于 2014-04-28T13:57:03.877 回答