{S0}摘要
如果你要检测数据流中的关键字或特殊的标记,通常使用一个解析器生成像YACC或{A}),在运行时创建一个在内存中的状态引擎。它具有低内存占用,是比任何标记生成器,字符串比较的方法可以更有效。{A3}{A4}{A5}
{A6}
一张手写的解析器/扫描器需要很多国家,看起来类似下面的一段代码:boost::tribool parser::consume(char input)
{
switch (state_)
{
case state_1:
if (input == 'P')
{
state_ = state_2;
return boost::indeterminate;
}
else
{
return false;
}
case state_2:
if (input == 'O')
{
return true;
}
... <snip> ...
default:
return false;
}
}
这是一个状态引擎的执行情况,并非常容易出错,如果你有管理很多国家。它工作正常,并为您提供快速,但有大量的工作,修改关键字。下面的代码片段显示了如何与tag_tree模板可以解决这个问题:{C}
()返回从数据流中的下一个字符。虽然findNode()是匹配的方法继续循环。打破循环,isLeaf()测试后,如果发现一个有效的关键字,该方法返回一个标识符。返回上一页指针本身是完全可能的。上一个点在任何情况下,以一个有效的地址,并包含了所有你需要的信息。它是如何工作
主要的想法是,每个关键字建立一个独特的联系节点,其中每个节点代表一个特定的解析器的状态跟踪。要构建此跟踪,一个数组的树将被使用。下图显示了一个树的关键字端口和POST:
这里来给你一些安慰。如果你喜欢对内存的速度,选择阵列的最大尺寸(256为char,例如)。然后选择最简单的哈希算法,这是可能的 - 作为数组索引的ASCII码。为了节省内存,阵列可能会萎缩。但是,我们有管理碰撞列表。
在下载部分,是一个名为标记树一个项目,该项目包含为tag_tree模板的使用更复杂的样品。参考tag_tree_base
定义为所有节点值的一些typedef和访问方法。 tag_tree_base不仅限于字符串。您可以使用任何串状的容器定义为常量和一个value_type的类型。
{A8}{A9}{A10}{A11}{A12}{A13}{A14}{A15}
参数:C:这个节点是代表的字符。{A16}tag_tree_base::tag_tree_base( char_type c );
返回值:value_type & tag_tree_base::getValue();
这个节点的价值。{A17}tag_tree::tag_tree( char_type c );
tag_tree是专为使用一个流解析器。 tag_tree可以帮助你在内存中构建紧凑型国家的发动机,因为每个节点代表一个独特的解析器的状态。参数:C:这个节点是代表的字符。
设置所有的指针为NULL是由容器完成。{A18}
参数:C:字符查找。返回值tag_tree::MyPtr_ tag_tree::findNode( char_type c );
一个节点包含指定的字符c或NULL指针。{A19}
返回值bool tag_tree::empty ( ) const;
如果没有传出节点指针。
语义的STL - 集装箱空()方法类似。如果该节点的数组nodeMap_包含没有指针,然后nodeList_应该不是非此即彼。它应该是叶。否则,这是错误的。
{A20}
返回值:size_t tag_tree::leaf_count( bool branch = false ) const;
从这个角度出发的关键字计数。
参数:OS:一个开放的输出流,性病::法院为例,。void tag_tree::dump( ostream_type_ & os,
size_t depth = 0L,
size_t branch = 0L
) const;
打印普通列表的所有节点及其属性。用于调试。{A22}
参数:从:输入迭代器,解决在关键字的第一个元素的位置。:一个输入迭代器,解决的立场,即是过去在关键字的最后一个元素之一。
返回值:tag_tree::lookUp( char_const_iterator from, char_const_iterator to ) const
该关键字的值。如果关键字不存在,将返回一个null值。
指定关键字查找。历史,2007年10月29日 - 初始版本。