gpt4 book ai didi

Ragel:避免冗余调用 "when"子句函数

转载 作者:行者123 更新时间:2023-12-01 15:11:32 26 4
gpt4 key购买 nike

我正在为相当简单的二进制协议(protocol)编写 Ragel 机器,我在这里展示的是更简化的版本,没有任何错误恢复,只是为了演示我试图解决的问题。

因此,这里要解析的消息如下所示:

<1 byte: length> <$length bytes: user data> <1 byte: checksum>

机器看起来如下:

%%{
machine my_machine;
write data;
alphtype unsigned char;
}%%

%%{
action message_reset {
/* TODO */
data_received = 0;
}

action got_len {
len = fc;
}

action got_data_byte {
/* TODO */
}

action message_received {
/* TODO */
}

action is_waiting_for_data {
(data_received++ < len);
}

action is_checksum_correct {
1/*TODO*/
}


len = (any);
fmt_separate_len = (0x80 any);
data = (any);
checksum = (any);

message =
(
# first byte: length of the data
(len @got_len)
# user data
(data when is_waiting_for_data @got_data_byte )*
# place higher priority on the previous machine (i.e. data)
<:
# last byte: checksum
(checksum when is_checksum_correct @message_received)
) >to(message_reset)
;

main := (msg_start: message)*;

# Initialize and execute.
write init;
write exec;
}%%

如你所见,首先我们收到代表长度的 1 个字节;然后我们接收 data 字节,直到我们收到所需的字节数(检查由 is_waiting_for_data 完成),当我们收到下一个(额外的)字节时,我们检查它是否是正确的校验和(通过 is_checksum_correct)。如果是,机器将等待下一条消息;否则,这台特定的机器会停止运行(为了简化图表,我故意没有在此处包括任何错误恢复)。

它的示意图是这样的:

$ ragel -Vp ./msg.rl | dot -Tpng -o msg.png

Click to see image

如您所见,在状态 1 中,当我们接收用户数据时,条件如下:

0..255(is_waiting_for_data, !is_checksum_correct),
0..255(is_waiting_for_data, is_checksum_correct)

因此在每个数据字节上它都冗余地调用 is_checksum_correct,尽管结果根本不重要。

条件应该很简单:0..255(is_waiting_for_data)

如何实现?

最佳答案

is_checksum_correct 应该如何工作?根据您发布的内容, when 条件发生在读取校验和之前。我的建议是检查 message_received 中的校验和并处理那里的任何错误。这样,您就可以摆脱第二个 when,问题将不再存在。

看起来语义条件是 Ragel 中的一个相对较新的功能,虽然它们看起来非常有用,但如果您想要优化代码,它们可能还不够成熟。

关于Ragel:避免冗余调用 "when"子句函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30955050/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com