【问题标题】:Ragel: avoid redundant call of "when" clause functionRagel:避免“when”子句函数的冗余调用
【发布时间】:2015-06-20 14:26:51
【问题描述】:

我正在为相当简单的二进制协议编写 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)

如何实现?

【问题讨论】:

    标签: ragel


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-16
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-10
      相关资源
      最近更新 更多