我很抱歉这个问题的通用标题,但我希望我能够更少地表达它。 : - }
我想编写一个软件(在这种情况下,使用C ++),它将输入令牌流转换为输出令牌流。只有五个输入令牌(让我们称之为0,1,2,3,4),每个令牌都有几个不同的属性(比如,可能有4.x属性或0.foo)。还有一些输出令牌,大约十个,让我们称之为(Out0..Out9),每个令牌也都有一些属性。
现在,我们一直致力于将输入令牌的序列映射到可能的输出令牌,如下所示:
01 -> Out0
34 -> Out1
0101 -> Out3
...因此不同的输入令牌序列映射到单个输出令牌。
在我的场景中,输入令牌集是固定的,但输出令牌集不是 - 我们可能会决定引入新的'制作'。我的问题是:
是否有人知道在这种情况下是否有好的模式和/或习语?
现在我有一组'Compressor'对象,每个对象都可以吃输入令牌并最终生成输出令牌。问题是一些输入令牌发生冲突,在上述情况下考虑'Out0'和'Out3'。输入'0101'应该产生Out3但不是 Out0。但是,输入'0104应该产生Out0,然后在队列中留下0和4。
我想知道是否有可能来自数据压缩或其他可能有益的领域的模式。
这种“降低”低级令牌输入到高级令牌并处理可能的冲突的工作在解析器编写者中很常见,不是吗?那里有有用的模式吗?
更新:
更多信息:
在我的具体情况中,输入标记是C结构,输出标记是C ++对象。我无法控制令牌的输入流,但我可以对它们进行排队,然后在有益的情况下修改队列。
我通过先尝试匹配Out3然后再尝试Out0来解决冲突(如Out3(0101)与Out0(01)),但它有点难看。可能的产品在列表中,我只是尝试将它们一个接一个地应用于输入流
可能的产品列表可以由用户扩展,因此我无法生成一个巨大的DAG,然后有一个状态机来实现它以处理每个可能的转换。当然,这意味着用户可以添加冲突,但就是这样。
答案 0 :(得分:1)
在设计数据压缩算法时,您需要注意一个代码的开头不能被误认为是另一个较短的代码。这是Hamming code的基础。另一种方法是使用分隔符来分隔您的令牌,例如摩尔斯电码(使用字符之间的短暂停顿)。
答案 1 :(得分:1)
多年前我会立即说看Bison http://www.gnu.org/software/bison/或Yacc,但我有一段时间没有这样做过,所以不知道有什么更好的。
使用它们对于你正在做的事情可能有点过头但是使用的习语可能有用。
答案 2 :(得分:1)
您可以定义一个图形,其中每个节点都包含一个输入标记和一个关联的输出。每个节点的链接描述了可能的下一个令牌。因此,图中的路径描述了可能的转换规则。
要转换数据,请从对应于第一个输入标记的节点开始,并尝试在尽可能最长的路径上导航图形,将下一个输入标记与链接到当前节点的节点相匹配。当没有链接节点与下一个输入节点匹配时,将与当前节点关联的输出作为结果。