﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-shifan3-随笔分类-Boost</title><link>http://www.cppblog.com/shifan3/category/3012.html</link><description>Everything is template...</description><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 11:26:24 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 11:26:24 GMT</pubDate><ttl>60</ttl><item><title>[yc]Xpressive简介</title><link>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 27 Jul 2006 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/10590.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/10590.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/10590.html</trackback:ping><description><![CDATA[Xpressive是一个C++的正则表达式库，目前是Boost的候选库。<br>Xpressive和Boost.Regex的区别很大。首先，Xpressive是一个纯头文件的库，也是说，在使用之前不需要预先编译。其次，Xpressive支持类似于Spirit的静态语义定义。<br><br>我们先来看一个例子：
<p>&#160;</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)">#include&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">iostream</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br>#include&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)">boost</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive.hpp</span><span style="COLOR: rgb(0,0,0)">&gt;</span><span style="COLOR: rgb(0,0,0)"><br><br></span><span style="COLOR: rgb(0,0,255)">using</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">namespace</span><span style="COLOR: rgb(0,0,0)">&nbsp;boost::xpressive;<br><br></span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)">&nbsp;main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;std::</span><span style="COLOR: rgb(0,0,255)">string</span><span style="COLOR: rgb(0,0,0)">&nbsp;hello(&nbsp;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">hello&nbsp;world!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">&nbsp;);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;sregex&nbsp;rex&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;sregex::compile(&nbsp;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">(\\w+)&nbsp;(\\w+)!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;smatch&nbsp;what;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">(&nbsp;regex_match(&nbsp;hello,&nbsp;what,&nbsp;rex&nbsp;)&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;whole&nbsp;match</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;first&nbsp;capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;what[</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&lt;&lt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;second&nbsp;capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">;<br>}</span></div>
<p>这是使用Xpressive动态语义定义的例子，其中sregex::compile函数编译一个表示正则文法的串，并返回一个正则对象sregex<br>使用regex_match来使用这个正则对象匹配一个串。结果储存在what内<br>其中what[0]返回整个串，what[1]~what[n]返回文法中用于标记的部分(用小括号括起来的部分)<br>最后将输出<br>&nbsp;&nbsp;&nbsp;&nbsp; hello world!<br>&nbsp;&nbsp;&nbsp;&nbsp; hello<br>&nbsp;&nbsp;&nbsp;&nbsp; world</p>
<p>如果想在一个串中查找符合该文法的子串，可以使用regex_search，用法和regex_match一样，此外还可以用regex_replace来进行替换。<br></p>
<p>&nbsp;</p>
<p><br>静态文法：<br>Xpressive除了可以用compile来分析一个文法串之外，还可以用类似于Spirit的方式来静态的指定文法：<br></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d;</span></div>
<p>这将定义一个表示金额的串，其中_d表示一个数字，相当于串 $\d+.\d\d<br>这样定义文法将比之前的动态定义更加高效，并且还有一个附加的好处：<br>分级定义：</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;_d;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>sregex&nbsp;s&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;re&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;</span></div>
<p>这样s表示为用括号括起来的re<br>通过分级定义，文法能被表示的更加清楚。<br>更加棒的是，分级定义还可以向后引用，因此能够分析EBNF</p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex&nbsp;group,&nbsp;factor,&nbsp;term,&nbsp;expression;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>group&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;by_ref(expression)&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>factor&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;group;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>term&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>expression&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;term&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term));</span></div>
<p>expression定义了一个四则表达式，注意其中group的定义。<br>这里必须使用by_ref是因为Xpressive默认是值拷贝，如果这里使用默认的方式，那么会造成一个无限循环。<br><br><br>Xpressive可以在这里下载<br><a href="http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&amp;direction=0&amp;order=&amp;directory=Strings%20-%20Text%20Processing&amp;PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535">http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&amp;direction=0&amp;order=&amp;directory=Strings%20-%20Text%20Processing&amp;PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535</a><br>内有详细的文档</p>
<img src ="http://www.cppblog.com/shifan3/aggbug/10590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-07-27 16:27 <a href="http://www.cppblog.com/shifan3/archive/2006/07/27/10590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]自己实现Lambda（第二部分）</title><link>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sat, 15 Jul 2006 07:32:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/10099.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/10099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/10099.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 发信人: shifan (家没有豚豚 T.T), 板面: C++标&nbsp; 题: 如何实现Lambda[第二部分]发信站: 飘渺水云间 (Thu Jun&nbsp; 8 23:30:20 2006), 转信章节:八:第一部分的小结九:简化,如何减少Lambda代码的冗余和依赖性十:bind的实现十一:实现phoenix八．&nbsp;&nbsp;&nbsp; 中期总结目前的结果是这样的...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/10099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-07-15 15:32 <a href="http://www.cppblog.com/shifan3/archive/2006/07/15/10099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]自己实现Lambda</title><link>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 09 Jun 2006 05:23:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/8334.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/8334.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/8334.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一．&nbsp;什么是Lambda所谓Lambda，简单的说就是快速的小函数生成。在C++中，STL的很多算法都要求使用者提供一个函数对象。例如for_each函数，会要求用户提供一个表明&#8220;行为&#8221;的函数对象。以vector&lt;bool&gt;为例，如果想使用for_each对其中的各元素全部赋值为true，一般需要这么一个函数对象，&nbsp; &nbsp; c...&nbsp;&nbsp;<a href='http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html'>阅读全文</a><img src ="http://www.cppblog.com/shifan3/aggbug/8334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2006-06-09 13:23 <a href="http://www.cppblog.com/shifan3/archive/2006/06/09/8334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]boost::spirit初体验</title><link>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sun, 18 Dec 2005 04:02:00 GMT</pubDate><guid>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html</guid><wfw:comment>http://www.cppblog.com/shifan3/comments/1857.html</wfw:comment><comments>http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/shifan3/comments/commentRss/1857.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/shifan3/services/trackbacks/1857.html</trackback:ping><description><![CDATA[<p><font face="Courier New">&nbsp;&nbsp;&nbsp; 最近为了解析SQL语法，怀着试一试的心态去翻了翻boost的spirit库，因为该库的文档的简介里写着LL parser framework&nbsp; represents parsers directly as EBNF grammars in inlined C++。看着framework这个词自然觉得这个库很牛B，试用了一下果然如此。<br>&nbsp;&nbsp;&nbsp; 所谓EBNF即扩展巴克斯范式，是一种描述Context-Free Language的文法。在目前常见的非自然语言中，大部分都可以用EBNF表示。例如：<br><span class=identifier>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;group&nbsp;&nbsp;</span><span class=special>::=</span><span class=literal>'('</span><span class=identifier><span class=identifier>exp </span></span></font><font face="Courier New"><span class=literal>')'<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>factor&nbsp;</span><span class=special>::=</span><span class=identifier>integer</span><span class=special>|</span></font> <font face="Courier New"><span class=identifier>group<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>term&nbsp;&nbsp;&nbsp;</span><span class=special>::=</span><span class=identifier>factor</span><span class=special>((</span><span class=literal>'*'</span><span class=identifier>factor</span><span class=special>)</span><span class=special>|</span><span class=special>(</span><span class=literal>'/'</span><span class=identifier>factor</span></font> <font face="Courier New"><span class=special>))*<br></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier>exp&nbsp;&nbsp;&nbsp;&nbsp;</span><span class=special>::=</span><span class=identifier>term</span><span class=special>((</span><span class=literal>'+'</span><span class=identifier>term</span><span class=special>)</span><span class=special>|</span><span class=special>(</span><span class=literal>'-'</span><span class=identifier>term</span></font> <span class=special><font face="Courier New">))*<br>这是一个整数表达式的EBNF。该段描述用spirit在C++中的实现则是：<br>&nbsp;&nbsp;&nbsp;</font> </span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;group,&nbsp;factor,&nbsp;term,&nbsp;exp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;group&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;exp&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;group;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;term&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;factor));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;exp&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;term&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term)&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;term));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">这里使用=代替::=, 用&gt;&gt;代替空格连接。并且由于C++语法所限，EBNF中后置的*在spirit中改为前置。<br>等式左边的单词被称为一个rule，等式右边为rule的定义。我们可以看出一个group是一个exp加上一对括号，一个factor是一个整数或者一个group,一个term是一个或多个factor用*/连接，一个exp是一个或多个term用+-连接。处于最顶端的exp可以据此识别出以下表达式<br></font><font face="Courier New"><span class=number>&nbsp;&nbsp;&nbsp;</span> </font></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;((</span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">200</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">20</span><span style="COLOR: rgb(0,0,0)">)&nbsp;</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;(</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">5</span><span style="COLOR: rgb(0,0,0)">))))<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; 得到一个rule之后，我们就可以用</font> <span class=identifier><font face="Courier New">parse函数对一个串进行识别了。例如<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font> </span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">(1&nbsp;+&nbsp;(2&nbsp;+&nbsp;(3&nbsp;+&nbsp;(4&nbsp;+&nbsp;5))))</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">,&nbsp;exp);</font> </span></div>
<p><font face="Courier New"><br>该函数返回一个结构parse_info，可以通过访问其中的full成员来判断是否成功识别，也可以访问stop成员来获知失败的位置。这里要特别提一点，关于各个符号之间的空格，spirit的文档的正文说的是给parse再传一个参数space_p，通知parse跳过所有的空格，然而在FAQ中又提到，如果使用以上方法定义rule，第三个参数传space_p会失败。原因是使用rule默认定义的规则被称为character level parsing，即字符级别解析，而parse的第3个参数仅适用于phrase level parsing，即语法级别解析。要使用第3个参数可以有几种方法。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1。在parse的第二个参数直接传入一个EBNF表达式，不创建rule对象。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=identifier></span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">hello&nbsp;world</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">,&nbsp;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">*</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">anychar_p,&nbsp;space_p);&nbsp;&nbsp;</font> </span></div>
<p><font face="Courier New"><span class=special><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2。以rule&lt;phrase_scanner_t&gt;创建rule。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </font></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&lt;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">phrase_scanner_t</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&gt;</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">&nbsp;exp;&nbsp;</font> </span></div>
<p><font face="Courier New">注意虽然可以用这两个办法屏蔽空格，但是这样可能完全改变EBNF文法的语义，尤其是在语言本身需要识别空格的时候。对于这种情况，可以不使用第三个参数，并在需要出现空格的地方加上space_p,或者+space_p及*space_p，其中+和*分别表示后面的符号连续出现一次以上和0次以上。例如一个以空格分隔的整数列表可以写成int_p &gt;&gt; *(+space_p &gt;&gt; int_p)<br>&nbsp;&nbsp; 如上使用parse可以识别一个串，但并不能做更多的操作，例如将语法里的各个成分提取出来。对于这样的需求，可以通过actor实现。下面是使用actor的一个简单例子<br>&nbsp;&nbsp;&nbsp;<span class=keyword></span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;<span style="COLOR: rgb(0,0,255)">bool</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;parse_numbers(</span><span style="COLOR: rgb(0,0,255)">char</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">&nbsp;str,&nbsp;vector</span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,255)">double</span><span style="COLOR: rgb(0,0,0)">&gt;&amp;</span><span style="COLOR: rgb(0,0,0)">&nbsp;v)<br><img id=Codehighlighter1_61_247_Open_Image onclick="this.style.display='none'; Codehighlighter1_61_247_Open_Text.style.display='none'; Codehighlighter1_61_247_Closed_Image.style.display='inline'; Codehighlighter1_61_247_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_61_247_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_61_247_Closed_Text.style.display='none'; Codehighlighter1_61_247_Open_Image.style.display='inline'; Codehighlighter1_61_247_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_61_247_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_61_247_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)">&nbsp;parse(str,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;&nbsp;Begin&nbsp;grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;real_p[push_back_a(v)]&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;real_p[push_back_a(v)])<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;,<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">&nbsp;&nbsp;End&nbsp;grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;space_p).full;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><font face="Courier New">注意到<span class=identifier>real_p后面的[]，中括号里面是一个仿函数（函数指针或者函数对象），该仿函数具有如下调用型别<br>&nbsp;&nbsp;&nbsp;</span></font> </p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(IterT&nbsp;first,&nbsp;IterT&nbsp;last)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(NumT&nbsp;val)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(CharT&nbsp;ch)&nbsp;</span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;</span></font> </div>
<p><span class=special><span class=special><span class=special><font face="Courier New"><br>一旦spase发现了匹配<span class=identifier>real_p的子串，就会调用该functor。不同的rule可能会对应不同的调用型别。</span><br>第一个型别针对一般规则，first和last为两个指向字符的迭代器（一般为char*）,匹配的子串为[first, last)<br>第二个型别针对数字型规则，如real_p和int_p, 参数val是一个数字类型。<br>第三个性别针对单字符型规则，如space_p, 参数ch是一个字符类型。<br><span class=identifier>real_p</span><span class=special>[</span><span class=identifier>push_back_a</span><span class=special>(</span><span class=identifier>v</span><span class=special>)]中的push_back_a是一个spirit已经定义好的functor，它会将匹配好的内容依照匹配到的时间顺序调用v的push_back函数加入到v中。<br><br>&nbsp;&nbsp;&nbsp;到此spirit的常用功能就都介绍完了。要详细深入了解可以参考spirit的文档。<br><br>最后在题一个注意要点。spirit的各种EBNF连接都是指针连接，因此才能在expression被赋值前就在group的定义里面使用。所以在使用EBNF的时候一定要小心不要将局部变量的rule提供给全局或者类成员变量使用，例如：<br>&nbsp;&nbsp;&nbsp;</span></font> </span></span></span></p>
<div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)">&nbsp;A<br><img id=Codehighlighter1_11_166_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_166_Open_Text.style.display='none'; Codehighlighter1_11_166_Closed_Image.style.display='inline'; Codehighlighter1_11_166_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_11_166_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_11_166_Closed_Text.style.display='none'; Codehighlighter1_11_166_Open_Image.style.display='inline'; Codehighlighter1_11_166_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_11_166_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_11_166_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;s;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A()<br><img id=Codehighlighter1_45_161_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_161_Open_Text.style.display='none'; Codehighlighter1_45_161_Closed_Image.style.display='inline'; Codehighlighter1_45_161_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_45_161_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_161_Closed_Text.style.display='none'; Codehighlighter1_45_161_Open_Image.style.display='inline'; Codehighlighter1_45_161_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_45_161_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_45_161_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rule</span><span style="COLOR: rgb(0,0,0)">&lt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;r&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;int_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)">&nbsp;hex_p;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s&nbsp;</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">&nbsp;r&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">space_p&nbsp;</span><span style="COLOR: rgb(0,0,0)">&gt;&gt;</span><span style="COLOR: rgb(0,0,0)">&nbsp;r);&nbsp;</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">error,&nbsp;r&nbsp;destructed&nbsp;after&nbsp;return&nbsp;</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div>
<p><span class=special><span class=identifier><font face="Courier New"><span class=special><span class=identifier><span class=special><span class=special><span class=special><span class=special>如果真想使用局部作用域，可以在局部的rule前面加上static.</span> </span></span></span></span></span></font></span></span></p>
<img src ="http://www.cppblog.com/shifan3/aggbug/1857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/shifan3/" target="_blank">shifan3</a> 2005-12-18 12:02 <a href="http://www.cppblog.com/shifan3/archive/2005/12/18/1857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>