[boost-doc-zh] r336 committed - Spirit库译文,由 alai04 翻译,第三批

  • From: codesite-noreply@xxxxxxxxxx
  • To: boost-doc-zh-notify@xxxxxxxxxxxxx
  • Date: Tue, 13 Oct 2009 03:28:03 +0000

Revision: 336
Author: alai04
Date: Mon Oct 12 20:27:43 2009
Log: Spirit库译文,由 alai04 翻译,第三批
http://code.google.com/p/boost-doc-zh/source/detail?r=336

Modified:
 /trunk/libs/spirit/classic/doc/acknowledgments.html
 /trunk/libs/spirit/classic/doc/debugging.html
 /trunk/libs/spirit/classic/doc/error_handling.html
 /trunk/libs/spirit/classic/doc/faq.html
 /trunk/libs/spirit/classic/doc/file_iterator.html
 /trunk/libs/spirit/classic/doc/includes.html
 /trunk/libs/spirit/classic/doc/multi_pass.html
 /trunk/libs/spirit/classic/doc/portability.html
 /trunk/libs/spirit/classic/doc/position_iterator.html
 /trunk/libs/spirit/classic/doc/quickref.html
 /trunk/libs/spirit/classic/doc/rationale.html
 /trunk/libs/spirit/classic/doc/references.html
 /trunk/libs/spirit/classic/doc/style_guide.html
 /trunk/libs/spirit/classic/doc/symbols.html
 /trunk/libs/spirit/classic/doc/techniques.html
 /trunk/libs/spirit/classic/doc/trees.html
 /trunk/libs/spirit/classic/index.html

=======================================
--- /trunk/libs/spirit/classic/doc/acknowledgments.html Tue Mar 31 01:07:16 2009 +++ /trunk/libs/spirit/classic/doc/acknowledgments.html Mon Oct 12 20:27:43 2009
@@ -1,30 +1,28 @@
-<html>
-<head>
-<title>Acknowledgments</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Acknowledgments</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
     <td width="85%">
- <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b><b>Acknowledgments</b></b></font> + <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b><b>Acknowledgments 鸣谢</b></b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="rationale.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <p>Special thanks to </p>
<p><b>Dan Nuffer</b> for his work on lexers, parse trees, ASTs, XML parsers, the multi-pass iterator as well as administering Spirit's site, editing, maintaining
@@ -34,9 +32,11 @@
utility parsers, the original port to Intel 5.0, various work on Phoenix, porting to v1.5, the meta-parsers, the grouping-parsers, extensive testing and painstaking
   attention to details.</p>
-<p><b>Martin Wille</b> who improved grammar multi thread safety, contributed the - eol_p parser, the dynamic parsers, documentation and for taking an active role - in almost every aspect from brainstorming and design to coding. And, as always, helps keep the regression tests for g++ on Linux as green as ever :-). </p>
+<p><b>Martin Wille</b> who improved grammar multi thread safety,
+contributed the eol_p parser, the dynamic parsers, documentation and
+for taking an active role in almost every aspect from brainstorming and
+design to coding. And, as always, helps keep the regression tests for
+g++ on Linux as green as ever :-). </p>
<p><b>Martijn W. Van Der Lee</b> our Web site administrator and for contributing
   the RFC821 parser<b>.</b></p>
<p><b>Giovanni Bajo</b> for last minute tweaks of Spirit 1.8.0 for CodeWarrior
@@ -48,7 +48,9 @@
<p><b>Juan Carlos Arevalo-Baeza (JCAB) </b>for his work on the C++ parser, the position iterator, ports to v1.5 and keeping the mailing list discussions alive
   and kicking.</p>
-<p><strong>Vaclav Vesely, </strong>lots of stuff, the no_actions directive, various patches fixes, the distinct parsers, the lazy parser, some phoenix tweaks and add-ons (e.g. <tt>new_</tt>). Also, <strong>Stefan&nbsp;Slapeta</strong> and <strong>wife</strong> for editing Vaclav's distinct parser doc. </p>
+<p><strong>Vaclav Vesely, </strong>lots of stuff, the no_actions
+directive, various patches fixes, the distinct parsers, the lazy
+parser, some phoenix tweaks and add-ons (e.g. <tt>new_</tt>). Also, <strong>Stefan&nbsp;Slapeta</strong> and <strong>wife</strong> for editing Vaclav's distinct parser doc. </p> <p><b>Raghavendra Satish </b>for doing the original v1.3 port to VC++ and his
     work on Phoenix.</p>
<p><b>Noah Stein</b> for following up and helping Ragav on the VC++ ports.</p>
@@ -64,7 +66,7 @@
   the file iterator.</p>
<p><b>Peter Simons</b> for the RFC date parser example and tutorial plus helping
   out with some nitty gritty details.</p>
-<p><b>Markus Sch&ouml;pflin</b> for suggesting the end_p parser and lots of other +<p><b>Markus Schöpflin</b> for suggesting the end_p parser and lots of other
   nifty things and his active presence in the mailing list.</p>
<p><b>Doug Gregor</b> for mentoring and his ability to see things that others
   don't. </p>
@@ -82,12 +84,16 @@
<p><strong>Steve Rowe</strong> for his splendid work on the TSTs that will soon
   be taken into Spirit.</p>
 <p><strong>Jonathan de Halleux</strong> for his work on actors.</p>
-<p><strong>Angus Leeming</strong> for last minute editing work on the 1.8.0 release documentation, his work on Phoenix and his active presence in the Spirit mailing list.</p>
+<p><strong>Angus Leeming</strong> for last minute editing work on the
+1.8.0 release documentation, his work on Phoenix and his active
+presence in the Spirit mailing list.</p>
<p> <strong>Joao Abecasis</strong> for his active presence in the Spirit mailing list, providing user support, participating in the discussions and so on. </p> <p> <strong>Guillaume Melquiond</strong> for a last minute patch to <tt>multi_pass</tt> for 1.8.1. </p> <p> <strong>Peder Holt</strong> for his porting work on Phoenix, Fusion and Spirit to VC6. </p>
 <p>To my wife <b>Mariel</b> who did the graphics in this document.</p>
-<p>My, there's a lot in this list! And it's a continuing list. I add people to this list everytime. I hope I did not forget anyone. If I missed<br>
+<p>My, there's a lot in this list! And it's a continuing list. I add
+people to this list everytime. I hope I did not forget anyone. If I
+missed<br>
 someone you know who has helped in any way, please inform me.</p>
<p> Special thanks also to people who gave feedback and valuable comments, particularly members of Boost and Spirit mailing lists. This includes all those who participated
@@ -128,19 +134,18 @@
comprised of extremely talented library authors who participate in the discussion
   and peer review of well crafted C++ libraries.</p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="rationale.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="references.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
   </font> </p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/debugging.html       Sat Sep 12 00:52:19 2009
+++ /trunk/libs/spirit/classic/doc/debugging.html       Mon Oct 12 20:27:43 2009
@@ -1,35 +1,35 @@
-<html>
-<head>
-<title>Debugging</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Debugging</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Debugging</b></font> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Debugging 调试</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>The top-down nature of Spirit makes the generated parser easy to micro- debug using the standard debugger bundled with the C++ compiler we are using. With recursive-descent, the parse traversal utilizes the hardware stack through C++ function call mechanisms. There are no difficult to debug tables or state machines that obscure the parsing logic flow. The stack trace we see in the debugger
-  follows faithfully the hierarchical grammar structure.</p>
+  follows faithfully the hierarchical grammar structure.<br>Spirit
+自上而下的本质使得生成的分析器很容易使用与我们所用的C++编译器捆绑在一起的标 准调试器来进行微型调试。通过递归下降,分析的遍历通过C++函数调用 +机制利用了硬件的堆栈。调试解析模糊逻辑流的表格或状态机并没有难度。我们在调 试器中所看到的堆栈跟踪忠实地遵守语法结构的层次。</p> <p> Since any production rule can initiate a parse traversal , it is a lot easier to pinpoint the bugs by focusing on one or a few rules. For relatively complex parsing tasks, the same way we write robust C++ programs, it is advisable to
@@ -37,13 +37,16 @@
subset of the complete grammar. That way, we can stress-test individual modules piecemeal until we reach the top-most module. For instance, when developing a scripting language, we can start with expressions, then move on to statements,
-  then functions, upwards until we have a complete grammar. </p>
+  then functions, upwards until we have a complete grammar.&nbsp;<br>因
+为任何产生式规则都可以启动一个分析遍历,所以就更容易通过集中关注一个或几个 规则来查明缺陷。对于相对复杂的分析任务,与我们编写强大的C++程序一 +样,建议基于每个模块来开发语法,每个模块都是完整语法的一个小子集。这样,我 们可以对单个模块进行压力测试,直至到达最顶层的模块。例如,在开发一种脚 +本语言时,我们可以从表达式开始,然后是语句,然后是函数,向上直至我们完成一 个完整的语法。</p> <p> At some point when the grammar gets quite complicated, it is desirable to visualize the parse traversal and see what's happening. There are some facilities in the framework that aid in the visualisation of the parse traversal for the
-  purpose of debugging. The following macros enable these features.</p>
+ purpose of debugging. The following macros enable these features.<br>当语 法变得足够复杂的某一点时,最好进行可视化的分析遍历,看看发生了什么。在框架中 有一些工具,可以帮助分析遍历的可视化,达到调试的目的。以下宏将启用这些功能。 </p>
 <a name="debugging_macros"></a>
-<h2>Debugging Macros</h2>
+<h2>Debugging Macros 调试所用的宏</h2>
 <a name="spirit_assert_exception"></a>
 <h3>BOOST_SPIRIT_ASSERT_EXCEPTION</h3>
<p> Spirit contains assertions that may activate when spirit is used incorrectly.
@@ -52,114 +55,122 @@
to the name of the class that you want to be thrown. This class's constructor will be passed a <tt>const char*</tt> stringified version of the file, line, and assertion condition, when it is thrown. If you want to totally disable the
-  assertion, <tt>#define NDEBUG</tt>.</p>
+ assertion, <tt>#define NDEBUG</tt>.<br>Spirit带有一些断言,它们会在 spirit被错误使用时激活。缺省情况下,这些断言使用标准库的 assert 宏。如果你希 望spirit抛出异常,则将 <tt>BOOST_SPIRIT_ASSERT_EXCEPTION</tt> + 定义为你要抛出的异常类。在被抛出时,该类的构造函数将被传入一个 <tt>const char*</tt>,其中记录了文件版本、行号和断言条件。如果想完全关闭断言,请 <tt>#define NDEBUG</tt>.</p>
 <a name="spirit_debug"></a>
 <h3>BOOST_SPIRIT_DEBUG</h3>
-<p>Define this to enable debugging.</p>
+<p>Define this to enable debugging.<br>定义此宏以激活调试。</p>
 <p>With debugging enabled, special output is generated at key points of the
parse process, using the standard output operator (<tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>) with <tt>BOOST_SPIRIT_DEBUG_OUT</tt> (default is <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></tt>,
-  see below) as its left operand.</p>
-<table width="80%" border="0" align="center">
-  <tr>
+ see below) as its left operand.<br>当调试被激活时,在分析过程的关键点将生 成一些特定的输出,输出的方式是使用标准输出操作符(<tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>)并 以 <tt>BOOST_SPIRIT_DEBUG_OUT</tt> (缺省为 <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></tt>,
+  见后)作为左操作数。</p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
<td class="note_box"><img src="theme/note.gif"> In order to use spirit's
     debugging support you must ensure that appropriate overloads of
<tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt> taking <tt>BOOST_SPIRIT_DEBUG_OUT</tt> as its left operand are available.
-    The expected semantics are those of the standard output operator.<br>
+ The expected semantics are those of the standard output operator.<br><img src="theme/note.gif">&nbsp;为了使用spirit的调试支持,你必 须确保以&nbsp;<tt>BOOST_SPIRIT_DEBUG_OUT</tt> 作为左操作数的合适 + <tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt> 是可用的。所期望的语义就是标准输出操作 符的语义。<br>
     <br>
     These overloads may be provided either within the namespace where the
corresponding class is declared (will be found through Argument Dependent Lookup) or [within an anonymous namespace] within <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt>,
     so it is visible where it is called.<br>
+这些重载可以在相应类被声明的名字空间中提供(通过ADL查找),也可以在 <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt> 中提供,这样在调用时它就是可见的。<br>
     <br>
<img src="theme/alert.gif"> Note in particular that when <tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt> is set, overloads of <tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt> - taking instances of the types used in closures as their right operands are required.<br> + taking instances of the types used in closures as their right operands are required.<br><img src="theme/alert.gif"> 注意,特别地,当 <tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt> + 被设置时,<tt><span class="identifier">operator</span><span class="special">&lt;&lt;</span></tt>
+    的重载所要求的右操作数是在闭包中所使用的类型的实例。<br>
     <br>
     You may find an example of overloading the output operator for
<tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>
-    in a <a href="faq.html#output_operator">related FAQ entry</a>.</td>
+ in a <a href="faq.html#output_operator">related FAQ entry</a>.<br>你可 在 <a href="faq.html#output_operator">相关FAQ条目</a> 中看到一个例子,示范了 用于 + <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>
+    的输出操作符重载。</td>
   </tr>
-</table>
+</tbody></table>

<p>By default, if the <tt>BOOST_SPIRIT_DEBUG</tt> macro is defined, all available debug output is generated. To fine tune the amount of generated text you can define the <tt>BOOST_SPIRIT_DEBUG_FLAGS</tt> constant to be equal of a combination
-  of the following flags:</p>
-<table width="90%" border="0" align="center">
-  <tr>
+ of the following flags:<br>缺省情况下,如果 <tt>BOOST_SPIRIT_DEBUG</tt> 宏被定义,将生成所有可用的调试输出。要细调生成文本的数量,你可以将 <tt>BOOST_SPIRIT_DEBUG_FLAGS</tt> 常量定义为以下标志位的组合:</p>
+<table align="center" border="0" width="90%">
+  <tbody><tr>
<td colspan="2" class="table_title"><b>Available flags to fine tune debug
-      output </b></td>
+      output 用于细调调试输出的标志 </b></td>
   </tr>
   <tr>
- <td width="29%" height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_NODES</tt></td> - <td width="71%" class="table_cells"><p>print information about nodes (general
-        for all parsers)</p></td>
+ <td class="table_cells" height="27" width="29%"><tt>BOOST_SPIRIT_DEBUG_FLAGS_NODES</tt></td> + <td class="table_cells" width="71%"><p>print information about nodes (general + for all parsers)</p><p>打印关于节点的信息(对所有分析器通用 )</p></td>
   </tr>
   <tr>
- <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_TREES</tt></td> + <td class="table_cells" height="27"><tt>BOOST_SPIRIT_DEBUG_FLAGS_TREES</tt></td> <td class="table_cells"><p>print information about parse trees and AST's (general
-        for all tree parsers)</p></td>
+ for all tree parsers)</p><p>打印关于分析树和AST的信息(对所有树分析 器通用)</p></td>
   </tr>
   <tr>
- <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt></td> + <td class="table_cells" height="27"><tt>BOOST_SPIRIT_DEBUG_FLAGS_CLOSURES</tt></td> <td class="table_cells">print information about closures (general for all
-      parsers with closures)</td>
+ parsers with closures)<br>打印关于闭包的信息(对所有带闭包的分析器通用 )</td>
   </tr>
   <tr>
- <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR</tt></td> - <td class="table_cells"><p>print information out of the <tt>esc_char_parser</tt></p></td> + <td class="table_cells" height="27"><tt>BOOST_SPIRIT_DEBUG_FLAGS_ESCAPE_CHAR</tt></td> + <td class="table_cells"><p>print information out of the <tt>esc_char_parser</tt></p><p>打印 <tt>esc_char_parser</tt> 的信息 <tt></tt></p></td>
   </tr>
   <tr>
- <td height="27" class="table_cells"><tt>BOOST_SPIRIT_DEBUG_FLAGS_SLEX</tt></td> - <td class="table_cells">print information out of the <tt>SLEX</tt> parser</td> + <td class="table_cells" height="27"><tt>BOOST_SPIRIT_DEBUG_FLAGS_SLEX</tt></td> + <td class="table_cells">print information out of the <tt>SLEX</tt> parser<br>打印 <tt>SLEX</tt> 分析器的信息</td>
   </tr>
-</table>
+</tbody></table>
 <p><a name="spirit_debug_out"></a> </p>
 <h3>BOOST_SPIRIT_DEBUG_OUT</h3>
<p> Define this to redirect the debugging diagnostics printout to somewhere else
-  (e.g. a file or stream). Defaults to <tt>std::cout</tt>.</p>
+ (e.g. a file or stream). Defaults to <tt>std::cout</tt>.<br>定义此宏可将 调试诊断输出重定向至其它地方(如某个文件或流)。缺省输出至 <tt>std::cout</tt>.</p>
 <a name="spirit_debug_token printer"></a>
 <h3>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</h3>
-<p> The <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> macro allows you to redefine the way characters are printed on the stream. </p> +<p> The <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> macro allows you to redefine the way characters are printed on the stream.<br>宏 <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> 允许你重定义打印至流的方式字符。 </p> <p>If <tt>BOOST_SPIRIT_DEBUG_OUT</tt> is of type <tt>StreamT</tt>, the character type is <tt>CharT</tt> and <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> is
-  defined to <tt>foo</tt>, it must be compatible with this usage:</p>
-<pre><code><span class=identifier> foo</span><span class=special>(</span><span class=identifier>StreamT</span><span class=special>, </span><span class=identifier>CharT</span><span class=special>)</span></code></pre> + defined to <tt>foo</tt>, it must be compatible with this usage:<br>如果 <tt>BOOST_SPIRIT_DEBUG_OUT</tt> 的类型为 <tt>StreamT</tt>,字符类型为 <tt>CharT</tt> 且 <tt>BOOST_SPIRIT_DEBUG_TOKEN_PRINTER</tt> 被定义为 <tt>foo</tt>,则它必须兼容于以下用法:</p> +<pre><code><span class="identifier"> foo</span><span class="special">(</span><span class="identifier">StreamT</span><span class="special">, </span><span class="identifier">CharT</span><span class="special">)</span></code></pre> <p>The default printer requires <tt>operator&lt;&lt;(StreamT, CharT)</tt> to be defined. Additionaly, if <tt>CharT</tt> is convertible to a normal character
   type (<tt>char</tt>, <tt>wchar_t</tt> or <tt>int</tt>), it prints control
- characters in a friendly manner (e.g., when it receives <span class=special>'\n'</span> it - actually prints the <span class=special>\</span> and <span class=special>n</span> charactes,
-instead of a newline).</p>
+ characters in a friendly manner (e.g., when it receives <span class="special">'\n'</span> it + actually prints the <span class="special">\</span> and <span class="special">n</span> charactes, +instead of a newline).<br>缺省的打印机要求 <tt>operator&lt;&lt;(StreamT, CharT)</tt> 被定义。另外,如果 <tt>CharT</tt> 可以转换为普通的字符类型 (<tt>char</tt>, <tt>wchar_t</tt> 或 <tt>int</tt>),则它会以一种友好的风格打 印控制字符(如,当它收到 <span class="special">'\n'</span> 时,实际打印的是 <span class="special">\</span> 和 <span class="special">n</span> 字符,而不 是换行)。</p>
 <a name="spirit_debug_print_some"></a>
 <h3>BOOST_SPIRIT_DEBUG_PRINT_SOME</h3>
<p> The <tt>BOOST_SPIRIT_DEBUG_PRINT_SOME</tt> constant defines the number of characters from the stream to be printed for diagnosis. This defaults to the
-  first 20 characters.</p>
+ first 20 characters.<br><tt>BOOST_SPIRIT_DEBUG_PRINT_SOME</tt> 常量定义了 从流至被打印的诊断信息的字符数量。缺省为头20个字符。</p>
 <p><a name="spirit_debug_tracenode"></a> </p>
 <h3>BOOST_SPIRIT_DEBUG_TRACENODE</h3>
<p> By default all parser nodes are traced. This constant may be used to redefine this default. If this is <tt>1</tt> (<tt>true</tt>), then tracing is enabled by default, if this constant is <tt>0</tt> (<tt>false</tt>), the tracing is disabled by default. This preprocessor constant is set to <tt>1 </tt>(<tt>true</tt>)
-  by default.</p>
+ by default.<br>缺省情况下,所有分析器节点都被跟踪。这个常量可用于重定义该 缺省行为。如果它为 <tt>1</tt> (<tt>true</tt>),则跟踪被缺省打开,如果该常量 为 <tt>0</tt> (<tt>false</tt>),则跟踪被缺省关闭。这个预处理器常量缺省被设 为 <tt>1 </tt>(<tt>true</tt>)。</p> <p>Please note, that the following <tt>BOOST_SPIRIT_DEBUG_...() </tt>macros are
-  to be used at function scope only.</p>
+ to be used at function scope only.<br>请注意,以下的 <tt>BOOST_SPIRIT_DEBUG_...() </tt>宏只能被用在函数作用域中。</p>
 <a name="spirit_debug_node_p_"></a>
 <h3>BOOST_SPIRIT_DEBUG_NODE(p)</h3>
-<p> Define this to print some debugging diagnostics for parser p. This macro</p> +<p> Define this to print some debugging diagnostics for parser p. This macro<br>定义此宏为分析器 p 打印某些调试诊断信息。该宏</p>
 <ul>
-  <li>Registers the parser name for debugging</li>
- <li>Enables/disables the tracing for parser depending on <tt>BOOST_SPIRIT_DEBUG_TRACENODE</tt></li>
+  <li>Registers the parser name for debugging<br>为调试注册分析器名</li>
+ <li>Enables/disables the tracing for parser depending on <tt>BOOST_SPIRIT_DEBUG_TRACENODE</tt><br>根据 <tt>BOOST_SPIRIT_DEBUG_TRACENODE</tt> 为分析器打开/关闭跟踪<tt></tt></li>
 </ul>
<p> <b>Pre-parse</b>: Before entering the rule, the rule name followed by a peek
-  into the data at the current iterator position is printed.</p>
+ into the data at the current iterator position is printed.<br><b>分析 前:</b>在进行规则之前,打印规则名及当前迭代器位置读入的数据。</p> <p> <b>Post-parse</b>: After parsing the rule, the rule name followed by a peek into the data at the current iterator position is printed. Here, <tt>'/'</tt> before the rule name flags a succesful match while <tt>'#'</tt> before the rule
-  name flags an unsuccesful match.</p>
-<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_NODE</tt></p>
+ name flags an unsuccesful match.<br><b>分析后:</b>在规则被分析之后,打印 规则名及当前迭代器位置读入的数据。在此,规则名之前的<tt>'/'</tt>表示成功匹 配,而规则名之前的<tt>'#'</tt>表示不成功的匹配。</p> +<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_NODE</tt><br>以下 是 <tt>BOOST_SPIRIT_DEBUG_NODE</tt> 的同义词</p>
 <ol>
   <li>BOOST_SPIRIT_DEBUG_RULE</li>
   <li>BOOST_SPIRIT_DEBUG_GRAMMAR</li>
@@ -168,8 +179,8 @@
 <h3>BOOST_SPIRIT_DEBUG_TRACE_NODE(p, flag)</h3>
<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective debugging. This is useful in situations where we want to debug just a hand picked set of
-  nodes.</p>
-<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p> + nodes.<br>类似于 <tt>BOOST_SPIRIT_DEBUG_NODE</tt>。另外还允许选择性调试。 当我们想只对部分节点调试时可用。</p> +<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt><br>以下是 <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt> 的同义词</p>
 <ol>
   <li>BOOST_SPIRIT_DEBUG_TRACE_RULE</li>
   <li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR</li>
@@ -179,29 +190,16 @@
<p> Similar to <tt>BOOST_SPIRIT_DEBUG_NODE</tt>. Additionally allows selective debugging and allows to specify the name used during debug printout. This is useful in situations where we want to debug just a hand picked set of nodes. - The <tt>name</tt> may be redefined in situations, where the parser parameter does not reflect the name of the parser to debug.</p> -<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt></p> + The <tt>name</tt> may be redefined in situations, where the parser parameter does not reflect the name of the parser to debug.<br>类似于 <tt>BOOST_SPIRIT_DEBUG_NODE</tt>。并允许选择性调试和在调试输出时指定名字。当 我们想只调试部分节点时可用。当分析器参数不能反映被调试分析器的名字 时,<tt>name</tt> 可用于重定义。</p> +<p> The following are synonyms for <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt><br>以下是 <tt>BOOST_SPIRIT_DEBUG_TRACE_NODE</tt> 的同义词</p>
 <ol>
   <li>BOOST_SPIRIT_DEBUG_TRACE_RULE_NAME</li>
   <li>BOOST_SPIRIT_DEBUG_TRACE_GRAMMAR_NAME</li>
 </ol>
 <hr>
-<p>Here's the original calculator with debugging features enabled:</p>
-<pre>
- <code><span class=preprocessor>#define </span><span class=identifier>BOOST_SPIRIT_DEBUG </span><span class=comment>///$$$ DEFINE THIS BEFORE ANYTHING ELSE $$$/// - </span><span class=preprocessor>#include </span><span class=string>&quot;boost/spirit/include/classic.hpp&quot;
-
-    </span><span class=comment>/***/
-
-    /*** CALCULATOR GRAMMAR DEFINITIONS HERE ***/
-
- </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>integer</span><span class=special>); - </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>group</span><span class=special>); - </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>factor</span><span class=special>); - </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>term</span><span class=special>); - </span><span class=identifier>BOOST_SPIRIT_DEBUG_RULE</span><span class=special>(</span><span class=identifier>expr</span><span class=special>);
-</span></code></pre>
-<p> <img src="theme/note.gif" width="16" height="16"> Be sure to add the macros <strong>inside</strong> the grammar definition's constructor. Now here's a sample session with the calculator.</p> +<p>Here's the original calculator with debugging features enabled:<br>以下 是带有调试功能的原始计算器:</p> +<pre> <code><span class="preprocessor">#define </span><span class="identifier">BOOST_SPIRIT_DEBUG </span><span class="comment">///$$$ DEFINE THIS BEFORE ANYTHING ELSE $$$///<br> </span><span class="preprocessor">#include </span><span class="string">"boost/spirit/include/classic.hpp"<br><br> </span><span class="comment">/***/<br><br> /*** CALCULATOR GRAMMAR DEFINITIONS HERE ***/<br><br> </span><span class="identifier">BOOST_SPIRIT_DEBUG_RULE</span><span class="special">(</span><span class="identifier">integer</span><span class="special">);<br> </span><span class="identifier">BOOST_SPIRIT_DEBUG_RULE</span><span class="special">(</span><span class="identifier">group</span><span class="special">);<br> </span><span class="identifier">BOOST_SPIRIT_DEBUG_RULE</span><span class="special">(</span><span class="identifier">factor</span><span class="special">);<br> </span><span class="identifier">BOOST_SPIRIT_DEBUG_RULE</span><span class="special">(</span><span class="identifier">term</span><span class="special">);<br> </span><span class="identifier">BOOST_SPIRIT_DEBUG_RULE</span><span class="special">(</span><span class="identifier">expr</span><span class="special">);<br></span></code></pre> +<p> <img src="theme/note.gif" height="16" width="16"> Be sure to add the macros <strong>inside</strong> the grammar definition's constructor. Now here's a sample session with the calculator.<br><img src="theme/note.gif" height="16" width="16"> 请确认将这些宏加在语法定义的构造函数<strong>内部 </strong>。以下是该计算器的一个会话示例。</p>

<pre><code> <span class="preprocessor">Type an expression...or [q or Q] to quit</span>

@@ -226,45 +224,42 @@
<span class="preprocessor">popped 1 and 2 from the stack. pushing 3 onto the stack.</span>
       /rule(expression):       ""
     /grammar(calc):    ""
-    <span class="preprocessor">-------------------------
-    Parsing succeeded
-    result = 3
-    -------------------------</span></code></pre>
-
-<p> We typed in &quot;1 + 2&quot;. Notice that there are two successful branches + <span class="preprocessor">-------------------------<br> Parsing succeeded<br> result = 3<br> -------------------------</span></code></pre>
+
+<p> We typed in "1 + 2". Notice that there are two successful branches
from the top rule <tt>expr</tt>. The text in red is generated by the parser's semantic actions while the others are generated by the debug-diagnostics of - our rules. Notice how the first <tt>integer</tt> rule took &quot;1&quot;, the - first <tt>term</tt> rule took &quot;+&quot; and finally the second <tt>integer</tt>
-  rule took &quot;2&quot;.</p>
+  our rules. Notice how the first <tt>integer</tt> rule took "1", the
+  first <tt>term</tt> rule took "+" and finally the second <tt>integer</tt>
+ rule took "2".<br>我们输入 "1 + 2"。注意,顶层规则 <tt>expr</tt> 有两个成 功的分支。红色的文本是由分析器的语义动作所生成,而其它文本是由我们规则的调试 诊断所生成。留意第一个 <tt>integer</tt> 规则是如何获得 "1",第一个 <tt>term</tt> 规则如何获得 "+" 以及最后,第二个 <tt>integer</tt>
+  如何获得 "2"。</p>
<p>Please note the special meaning of the first characters appearing on the printed
-  lines:</p>
+  lines:<br>请注意,出现在打印行的第一个字符的特殊意义:</p>
 <ul>
<li>a single <span class="literal">'/'</span> starts a line containing the information about a successfully matched parser node (<tt>rule&lt;&gt;</tt>, <tt>grammar&lt;&gt;</tt>
-    or <tt>subrule&lt;&gt;</tt>)</li>
+ or <tt>subrule&lt;&gt;</tt>)<br>以单个 <span class="literal">'/'</span> 开始的行,包含了一个成功匹配的分析器节点 (<tt>rule&lt;&gt;</tt>, <tt>grammar&lt;&gt;</tt> 或 <tt>subrule&lt;&gt;</tt>)的信息</li> <li>a single <span class="literal">'#'</span> starts a line containing the information
-    about a failed parser node</li>
+ about a failed parser node<br>以单个 <span class="literal">'#'</span> 开始的行,包含了一个失败的分析器节点的信息</li> <li>a single <span class="literal">'^'</span> starts a line containing the first member (return value/synthesised
-    attribute) of the closure of a successfully matched parser node.</li>
+ attribute) of the closure of a successfully matched parser node.<br>以 单个 <span class="literal">'^'</span> 开始的行,包含了一个成功匹配的分析器节 点的闭包的第一个成员(返回值/synthesised属性attribute)。</li>
 </ul>
-<p>Check out <a href="../example/fundamental/calc_debug.cpp">calc_debug.cpp</a> to see debugging in action. </p> +<p>Check out <a href="../example/fundamental/calc_debug.cpp">calc_debug.cpp</a> to see debugging in action.<br>关于调试的运作,请查看 <a href="../example/fundamental/calc_debug.cpp">calc_debug.cpp</a>。 </p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="position_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="error_handling.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
-  Copyright &copy; 2003 Hartmut Kaiser<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
+  Copyright © 2003 Hartmut Kaiser<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/error_handling.html Tue Mar 31 01:07:16 2009 +++ /trunk/libs/spirit/classic/doc/error_handling.html Mon Oct 12 20:27:43 2009
@@ -1,103 +1,87 @@
-<html>
-<head>
-<title>Error Handling</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Error Handling</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Error
-      Handling </b></font></td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Error
+      Handling 错误处理 </b></font></td>
+ <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="debugging.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="quickref.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>C++'s exception handling mechanism is a perfect match for error handling in the framework. Imagine a complete parser as a maze. At each branch, the input dictates where we will turn. Given an erroneous input, we may reach a dead end. If we ever reach one, it would be a waste of time to backtrack from where we came from. Instead, we supply guards in strategic points. Beyond a certain point, - we put put parser assertions in places where one is not allowed to go. </p> + we put put parser assertions in places where one is not allowed to go.<br>C+ ++的异常处理机制是对本框架中的错误处理的完美匹配。想象一下,一个完整的分析器 就象一个迷宫一样。在每一个分支,输入支配着我们向哪里转。给定一个错误 +的输入,我们可能会达到一个死胡同。如果我们达到了一个死胡同,就要浪费时间回 到我们的来处。相反,我们战略要点提供了防护(guard)。超出了某一
+点,我们把断言置于分析器中不得进入的地方。 </p>
<p>The assertions are like springs that catapult us back to the guard. If we ever reach a brick wall given a specific input pattern, everything unwinds quickly and we are thrown right back to the guard. This can be a very effective optimization when used wisely. Right back at the guard, we have a chance to correct the situation,
-  if possible. The following illustration depicts the scenario.</p>
-<table border="0" align="center">
-  <tr>
-    <td><img src="theme/error_handling.png" width="313" height="238"></td>
+ if possible. The following illustration depicts the scenario.<br>这种断言 就象弹簧一样将我们弹回到防护处。如果我们在某个特定的输入模式下到达死胡同,所 有东西都会迅速回退,我们被抛至刚好在防护之后。在正确使用时,这是一个非常有效 的优化。恰好在防护之后,我们有机会纠正这种情况,如果可能的话。下面的插图描绘 了这种场景。</p>
+<table align="center" border="0">
+  <tbody><tr>
+    <td><img src="theme/error_handling.png" height="238" width="313"></td>
   </tr>
-</table>
+</tbody></table>
 <a name="the_parser_exception"></a>
-<h2>Parser Errors</h2>
+<h2>Parser Errors 分析器错误</h2>
<p> The <tt>parser_error</tt> class is the generic parser exception class used
-  by Spirit. This is the base class for all parser exceptions.</p>
-<pre> <code><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ErrorDescrT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>IteratorT </span><span class=special>= </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*&gt; - </span><span class=keyword>class </span><span class=identifier>parser_error </span><span class=special>
-    {
-    </span><span class=keyword>public</span><span class=special>:
- </span><span class=identifier>parser_error</span><span class=special>(</span><span class=identifier>IteratorT </span><span class=identifier>where</span><span class=special>, </span><span class=identifier>ErrorDescrT </span><span class=identifier>descriptor</span><span class=special>); - </span><span class=identifier>IteratorT </span><span class=identifier>where</span><span class=special>; - </span><span class=identifier>ErrorDescrT</span><span class=identifier> descriptor</span><span class=special>;
-    </span><span class=special>};
-</span></code></pre>
+ by Spirit. This is the base class for all parser exceptions.<br><tt>parser_error</tt> 类是Spirit使用的泛型分析器异常类。它是 所有分析器异常的基类。</p> +<pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ErrorDescrT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">IteratorT </span><span class="special">= </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">*&gt;<br> </span><span class="keyword">class </span><span class="identifier">parser_error </span><span class="special">
+    {
+ </span><span class="keyword">public</span><span class="special">:<br> </span><span class="identifier">parser_error</span><span class="special">(</span><span class="identifier">IteratorT </span><span class="identifier">where</span><span class="special">, </span><span class="identifier">ErrorDescrT </span><span class="identifier">descriptor</span><span class="special">);<br> </span><span class="identifier">IteratorT </span><span class="identifier">where</span><span class="special">;<br> </span><span class="identifier">ErrorDescrT</span><span class="identifier"> descriptor</span><span class="special">;<br> </span><span class="special">};<br></span></code></pre> <p> The exception holds the iterator position where the error was encountered in its <tt>where</tt> member variable. In addition to the iterator, <tt>parser_error</tt> also holds information regarding the error (error descriptor) in its <tt>descriptor
-  </tt> member variable.</p>
+ </tt> member variable.<br>该异常将发生错误的迭代器位置保存于它的 <tt>where</tt> 成员变量。除了这个迭代器,<tt>parser_error</tt> + 还将与错误相关的信息(错误描述符)保存于它的 <tt>descriptor </tt>成员变量。 </p> <p> Semantic actions are free to throw parser exceptions when necessary. A utility function <tt>throw_</tt> may be called. This function creates and throws a <tt>parser_error</tt>
-  given an iterator and an error descriptor:</p>
-<pre>
- <code><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ErrorDescrT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>&gt; - </span><span class=keyword>void </span><span class=identifier>throw_</span><span class=special>(</span><span class=identifier>IteratorT where</span><span class=special>, </span><span class=identifier>ErrorDescrT descriptor</span><span class=special>);
-</span></code></pre>
+ given an iterator and an error descriptor:<br>当需要时语义动作可随意抛出 分析器异常。可以调用工具函数 <tt>throw_</tt>。该函数根据给定的一个迭代器和一 个错误描述符创建并抛出一个 <tt>parser_error</tt>。</p> +<pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ErrorDescrT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">&gt;<br> </span><span class="keyword">void </span><span class="identifier">throw_</span><span class="special">(</span><span class="identifier">IteratorT where</span><span class="special">, </span><span class="identifier">ErrorDescrT descriptor</span><span class="special">);<br></span></code></pre>
 <a name="the_parser_assertion"></a>
-<h2>Parser Assertions</h2>
+<h2>Parser Assertions 分析器断言</h2>
<p> Assertions may be put in places where we don't have any other option other than expect parsing to succeed. If parsing fails, a specific type of exception
-  is thrown.</p>
-<p> Before declaring the grammar, we declare some assertion objects. <tt>assertion</tt> + is thrown.<br>断言可以放在那些除了分析成功以外别无选择的地方。如果分析失 败,特定类型的异常将被抛出。</p><p> Before declaring the grammar, we declare some assertion objects. <tt>assertion</tt> is a template class parameterized by the type of error that will be thrown once the assertion fails. The following assertions are parameterized by a user defined
-  Error enumeration.</p>
+ Error enumeration.<br>在声明该语法之前,我们声明了一些断言对象。 <tt>assertion</tt> + 是一个模板类,以断言失败时抛出的异常类型参数化。以下例子中的断言由一个用 户自定义的
+  Error 枚举类型参数化。</p>
 <a name="examples"></a>
-<h3>Examples</h3>
-<pre>
-    <code><span class=keyword>enum </span><span class=identifier>Errors
-    </span><span class=special>{
- </span><span class=identifier>program_expected</span><span class=special>, - </span><span class=identifier>begin_expected</span><span class=special>,
-        </span><span class=identifier>end_expected
-    </span><span class=special>};
-
- </span><span class=identifier>assertion</span><span class=special>&lt;</span><span class=identifier>Errors</span><span class=special>&gt; </span><span class=identifier>expect_program</span><span class=special>(</span><span class=identifier>program_expected</span><span class=special>); - </span><span class=identifier>assertion</span><span class=special>&lt;</span><span class=identifier>Errors</span><span class=special>&gt; </span><span class=identifier>expect_begin</span><span class=special>(</span><span class=identifier>begin_expected</span><span class=special>); - </span><span class=identifier>assertion</span><span class=special>&lt;</span><span class=identifier>Errors</span><span class=special>&gt; </span><span class=identifier>expect_end</span><span class=special>(</span><span class=identifier>end_expected</span><span class=special>);
-</span></code></pre>
+<h3>Examples 例子</h3>
+<pre> <code><span class="keyword">enum </span><span class="identifier">Errors<br> </span><span class="special">{<br> </span><span class="identifier">program_expected</span><span class="special">,<br> </span><span class="identifier">begin_expected</span><span class="special">,<br> </span><span class="identifier">end_expected<br> </span><span class="special">};<br><br> </span><span class="identifier">assertion</span><span class="special">&lt;</span><span class="identifier">Errors</span><span class="special">&gt; </span><span class="identifier">expect_program</span><span class="special">(</span><span class="identifier">program_expected</span><span class="special">);<br> </span><span class="identifier">assertion</span><span class="special">&lt;</span><span class="identifier">Errors</span><span class="special">&gt; </span><span class="identifier">expect_begin</span><span class="special">(</span><span class="identifier">begin_expected</span><span class="special">);<br> </span><span class="identifier">assertion</span><span class="special">&lt;</span><span class="identifier">Errors</span><span class="special">&gt; </span><span class="identifier">expect_end</span><span class="special">(</span><span class="identifier">end_expected</span><span class="special">);<br></span></code></pre> <p> The example above uses enums to hold the information regarding the error, we are free to use other types such as integers and strings. For example, <tt>assertion&lt;string&gt;</tt> accepts a string as its info. It is advisable to use light-weight objects though, after all, error descriptors are usually static. Enums are convenient for error - handlers to detect and easily catch since C++ treats enums as unique types.</p>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"> <b><img src="theme/lens.gif" width="15" height="16"> + handlers to detect and easily catch since C++ treats enums as unique types.<br>以上例子用枚举类型来保存错误信息,我们也可以随意使用其它类型,如整 数或字符串。例如,<tt>assertion&lt;string&gt;</tt> + 接受一个字符串作为其信息。尽管使用轻量级对象是明智的,但毕竟错误描述符通 常都是静态的。枚举类型便于错误处理器进行检测,且容易捕获,因为C++将枚举类型 视为单独的类型。</p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"> <b><img src="theme/lens.gif" height="16" width="15">
       The assertive_parser</b><br>
       <br>
- Actually, the expression <tt>expect_end(str_p(&quot;end&quot;))</tt>creates
+      Actually, the expression <tt>expect_end(str_p("end"))</tt>creates
an assertive_parser object. An assertive_parser is a parser that throws an exception in response to a parsing failure. The assertive_parser throws a parser_error exception rather than returning an unsuccessful match to
@@ -105,40 +89,40 @@
are given an iterator of type <tt>IteratorT</tt>. This is combined with the error descriptor type <tt>ErrorDescrT</tt> of the assertion (in this case enum <tt>Errors</tt>). Both are used to create a <tt>parser_error&lt;Errors, - IteratorT&gt;</tt> which is then thrown to signal the exception. </td> + IteratorT&gt;</tt> which is then thrown to signal the exception.<br>实际上,表达式 <tt>expect_end(str_p("end"))</tt>创
+建一个 assertive_parser 对象。一个 assertive_parser
+是一个在分析失败时抛出异常的分析器。assertive_parser 抛出 parser_error
+异常而不是返回一个不成功匹配来表示分析器与输入匹配失败。在分析过程中,分析 器被给定一个类型为 <tt>IteratorT</tt> 的迭代器。它与断言的错误描述符(在这个 例子中是枚举类型 <tt>Errors</tt>)类型 <tt>ErrorDescrT</tt> 相组合。这两者均 被用于创建 <tt>parser_error&lt;Errors,
+      IteratorT&gt;</tt>,然后抛出以表示异常。 </td>
   </tr>
-</table>
+</tbody></table>
<p> The predeclared <tt>expect_end</tt> assertion object may now be used in the
-  grammar as wrappers around parsers. For example:</p>
-<pre>
- <code><span class=identifier>expect_end</span><span class=special>(</span><span class=identifier>str_p</span><span class=special>(</span><span class=string>&quot;end&quot;</span><span class=special>))
-</span></code></pre>
-<p> This will throw an exception if it fails to see &quot;end&quot; from the input.</p> + grammar as wrappers around parsers. For example:<br>现在,预先声明的 <tt>expect_end</tt> 断言对象可在语法中用作分析器之外的包装。例如:</p> +<pre> <code><span class="identifier">expect_end</span><span class="special">(</span><span class="identifier">str_p</span><span class="special">(</span><span class="string">"end"</span><span class="special">))<br></span></code></pre> +<p> This will throw an exception if it fails to see "end" from the input.<br>如果未能从输入中遇到 "end",将抛出一个异常。</p>
 <a name="the_guard"></a>
-<h2>The Guard</h2>
+<h2>The Guard 防护</h2>
<p> The <tt>guard</tt> is used to catch a specific type of <tt>parser_error</tt>. guards are typically predeclared just like assertions. Extending our previous
-  example:</p>
-<pre>
- <code><span class=identifier>guard</span><span class=special>&lt;</span><span class=identifier>Errors</span><span class=special>&gt; </span><span class=identifier>my_guard</span><span class=special>;
-</span></code></pre>
+ example:<br><tt>guard</tt> 用于捕获一个特定类型的 <tt>parser_error</tt>。 防护通常象断言一样预先声明。扩展一下我们前面的例子:</p> +<pre> <code><span class="identifier">guard</span><span class="special">&lt;</span><span class="identifier">Errors</span><span class="special">&gt; </span><span class="identifier">my_guard</span><span class="special">;<br></span></code></pre> <p> <tt>Errors</tt>, in this example is the error descriptor type we want to detect. This is the same enum as above. <tt>my_guard</tt> may now be used in a grammar
-  declaration:</p>
-<pre> <code><span class=identifier>my_guard</span><span class=special>(</span><span class=identifier>p</span><span class=special>)[</span><span class=identifier>error_handler</span><span class=special>]</span></code></pre> + declaration:<br><tt>Errors</tt>, 在本例中是我们想要检测的错误描述符类型。 它与前面的枚举类型一样。<tt>my_guard</tt> 可以被用在语法声明中:</p> +<pre> <code><span class="identifier">my_guard</span><span class="special">(</span><span class="identifier">p</span><span class="special">)[</span><span class="identifier">error_handler</span><span class="special">]</span></code></pre> <p> where <tt>p</tt> is an expression that evaluates to a parser. Somewhere inside <tt>p</tt>, a parser may throw a parser exception. <tt>error_handler</tt> is - the error handler which may be a function or functor compatible with the interface:</p> -<pre> <code>error_status<span class=special>&lt;</span>T<span class=special>&gt;</span><span class=identifier> - f</span><span class=special>(</span>ScannerT const&amp; scan, ErrorT error<span class=special>);
-</span></code></pre>
+ the error handler which may be a function or functor compatible with the interface:<br>其中 <tt>p</tt> 是一个被求值为分析器的表达式。在 + <tt>p</tt> 内部,分析器可以抛出分析器异常。<tt>error_handler</tt> 是错误 处理器,它可以是兼容于以下接口的函数或仿函数:</p> +<pre> <code>error_status<span class="special">&lt;</span>T<span class="special">&gt;</span><span class="identifier"> + f</span><span class="special">(</span>ScannerT const&amp; scan, ErrorT error<span class="special">);<br></span></code></pre> <p> Where scan points to the scanner state prior to parsing and error is the error that arose. The handler is allowed to move the scanner position as it sees fit, possibly in an attempt to perform error correction. The handler must then return
-  an <tt>error_status&lt;T&gt;</tt> object. </p>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"> <b><img src="theme/lens.gif" width="15" height="16"> + an <tt>error_status&lt;T&gt;</tt> object.<br>其中 scan 指向分析前的扫描器 状态,而 error 则是发生的错误。这个处理器允许将扫描器位置移至它认为合适的地 方,可以试图执行错误纠正。该处理器必须返回一个 <tt>error_status&lt;T&gt;</tt> 对象。 </p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"> <b><img src="theme/lens.gif" height="16" width="15">
       The fallback_parser </b><br>
       <br>
The expression <tt>my_guard(expr, error_handler)</tt>creates a fallback_parser
@@ -146,67 +130,53 @@
type. Since <tt>my_guard</tt> is declared as <tt>guard&lt;Errors&gt;</tt>, the fallback_parser catches <tt>Errors</tt> specific parser errors: <tt>parser_error&lt;Errors, IteratorT&gt;</tt>. The class sets up a try block. When an exception is
-      caught, the catch block then calls the error_handler. </td>
+ caught, the catch block then calls the error_handler.<br>表达式 <tt>my_guard(expr, error_handler)</tt> 创建一个 fallback_parser + 对象。fallback_parser 处理特定类型的parser_error 异常。由于 <tt>my_guard</tt> 被声明为 <tt>guard&lt;Errors&gt;</tt>,所以 fallback_parser 捕获 <tt>Errors</tt> 指定的分析器错 误:<tt>parser_error&lt;Errors, + IteratorT&gt;</tt>。该类设置一个 try 块。捕捉到一个异常后,catch 块将 调用该 error_handler. </td>
   </tr>
-</table>
+</tbody></table>
 <h2>error_status&lt;T&gt;</h2>
-<pre>
- <code><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T </span><span class=special>= </span><span class=identifier>nil_t</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>error_status
-    </span><span class=special>{
- </span><span class=keyword>enum </span><span class=identifier>result_t </span><span class=special>{ </span><span class=identifier>fail</span><span class=special>, </span><span class=identifier>retry</span><span class=special>, </span><span class=identifier>accept</span><span class=special>, </span><span class=identifier>rethrow </span><span class=special>};
-
- </span><span class=identifier>error_status</span><span class=special>(</span><span class=identifier> - result_t result </span><span class=special>= </span><span class=identifier>fail</span><span class=special>, - </span><span class=keyword>int </span><span class=identifier>length </span><span class=special>= -</span><span class=number>1</span><span class=special>, - </span><span class=identifier>T </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>value </span><span class=special>= </span><span class=identifier>T</span><span class=special>());
-</span>
- <span class=identifier>result_t result</span><span class=special>; - </span><span class=keyword>int </span><span class=identifier>length</span><span class=special>; - </span><span class=identifier>T value</span><span class=special>;
-    };</span></code></pre>
+<pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">T </span><span class="special">= </span><span class="identifier">nil_t</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">error_status<br> </span><span class="special">{<br> </span><span class="keyword">enum </span><span class="identifier">result_t </span><span class="special">{ </span><span class="identifier">fail</span><span class="special">, </span><span class="identifier">retry</span><span class="special">, </span><span class="identifier">accept</span><span class="special">, </span><span class="identifier">rethrow </span><span class="special">};<br><br> </span><span class="identifier">error_status</span><span class="special">(</span><span class="identifier"> + result_t result </span><span class="special">= </span><span class="identifier">fail</span><span class="special">, <br> </span><span class="keyword">int </span><span class="identifier">length </span><span class="special">= -</span><span class="number">1</span><span class="special">, <br> </span><span class="identifier">T </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">value </span><span class="special">= </span><span class="identifier">T</span><span class="special">());<br></span> <br> <span class="identifier">result_t result</span><span class="special">;<br> </span><span class="keyword">int </span><span class="identifier">length</span><span class="special">;<br> </span><span class="identifier">T value</span><span class="special">;<br> };</span></code></pre> <p>Where <tt>T</tt> is an attribute type compatible with the match attribute of the <tt>fallback_parser</tt>'s subject (defaults to <tt>nil_t</tt>). The class <tt>error_status</tt> reports the result of an error handler. This result can
-  be one of: </p>
-<table width="90%" border="0" align="center">
-  <tr>
-    <td class="table_title" colspan="8"> error_status result </td>
+ be one of:<br>其中 <tt>T</tt> 为一个属性类型,兼容于 <tt>fallback_parser</tt> 的主题的匹配属性(缺省为 <tt>nil_t</tt>)。类 + <tt>error_status</tt> 报告错误处理器的结果。该结果为以下之一:</p><table align="center" border="0" width="90%"><tbody><tr><td class="table_title" colspan="8">error_status result </td>
   </tr>
   <tr>
-  <tr>
+  </tr><tr>
     <td class="table_cells"><b>fail</b></td>
-    <td class="table_cells">quit and fail. Return a <tt>no_match</tt></td>
+ <td class="table_cells">quit and fail. Return a <tt>no_match<br></tt>退 出并失败。返回 <tt>no_match</tt></td>
   </tr>
-    <td class="table_cells"><b>retry</b></td>
- <td class="table_cells">attempt error recovery, possibly moving the scanner</td>
+    <tr><td class="table_cells"><b>retry</b></td>
+ <td class="table_cells">attempt error recovery, possibly moving the scanner<br>试图修复错误,可能移动扫描器</td>
   </tr>
-    <td class="table_cells"><b>accept</b></td>
+    <tr><td class="table_cells"><b>accept</b></td>
<td class="table_cells">force success returning a matching length, moving the
-    scanner appropriately and returning an attribute value</td>
+ scanner appropriately and returning an attribute value<br>强制成功返回 一个匹配长度,正确移动扫描器并返回一个属性值</td>
   </tr>
-    <td class="table_cells"><b>rethrow</b></td>
-  <td class="table_cells">rethrows the error</td>
+    <tr><td class="table_cells"><b>rethrow</b></td>
+  <td class="table_cells">rethrows the error<br>重新抛出该错误</td>
   </tr>
-</table>
-<p><img src="theme/lens.gif" width="15" height="16"> See <a href="../example/fundamental/error_handling.cpp">error_handling.cpp</a> for a compilable example. This is part of the Spirit distribution.</p>
-<table width="80%" border="0" align="center">
+</tbody></table>
+<p><img src="theme/lens.gif" height="16" width="15"> See <a href="../example/fundamental/error_handling.cpp">error_handling.cpp</a> for a compilable example. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 可编译示例请见 <a href="../example/fundamental/error_handling.cpp">error_handling.cpp</a>。这 是Spirit发布包的一部分。</p>
+<table align="center" border="0" width="80%">
 </table>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="debugging.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="quickref.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/faq.html     Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/faq.html     Mon Oct 12 20:27:43 2009
@@ -1,60 +1,56 @@
-<html>
-<head>
-<title>FAQ</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>FAQ</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>FAQ</b></font></td> - <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>FAQ 常见问题</b></font></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="techniques.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="rationale.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <ul>
-  <li><a href="#scanner_business">The Scanner Business</a></li>
-  <li><a href="#left_recursion">Eliminating Left Recursion</a> </li>
- <li><a href="#right_associativity">Implementing Right Associativity</a></li>
-  <li><a href="#lexeme_and_rules">The lexeme_d directive and rules</a></li>
-  <li><a href="#kleene_star">Kleene Star infinite loop</a></li>
+  <li><a href="#scanner_business">The Scanner Business 扫描器事务</a></li>
+ <li><a href="#left_recursion">Eliminating Left Recursion 消除左递归</a> </li> + <li><a href="#right_associativity">Implementing Right Associativity 实现 右关联</a></li> + <li><a href="#lexeme_and_rules">The lexeme_d directive and rules &nbsp; lexeme_d指示符和规则</a></li> + <li><a href="#kleene_star">Kleene Star infinite loop 克林星无限循环 </a></li>
   <li><a href="#CVS">Boost CVS and Spirit CVS</a></li>
<li><a href="#compilation_times">How to reduce compilation times with complex
-    Spirit grammars</a></li>
- <li><strong><a href="#frame_assertion">Closure frame assertion</a></strong></li>
-  <li><strong><a href="#greedy_rd">Greedy RD</a></strong></li>
+    Spirit grammars 如何减少复杂Spirit语法的编译时间</a></li>
+ <li><strong><a href="#frame_assertion">Closure frame assertion 闭包帧断言 </a></strong></li>
+  <li><strong><a href="#greedy_rd">Greedy RD 贪心RD</a></strong></li>
<li><strong><a href="#referencing_a_rule_at_construction">Referencing a rule
-    at construction time</a></strong></li>
-  <li><strong><a href="#storing_rules">Storing Rules</a></strong></li>
- <li><strong><a href="#parsing_ints_and_reals">Parsing ints and reals</a> </strong></li>
+    at construction time 在构造期引用规则</a></strong></li>
+ <li><strong><a href="#storing_rules">Storing Rules 保存规则 </a></strong></li> + <li><strong><a href="#parsing_ints_and_reals">Parsing ints and reals 分析 整数和实数</a> </strong></li> <li><strong><a href="#output_operator">BOOST_SPIRIT_DEBUG and missing <tt>operator&lt;&lt;</tt></a></strong></li> - <li><strong><a href="#repository">Applications that used to be part of spirit</a></strong></li> + <li><strong><a href="#repository">Applications that used to be part of spirit 以前作为spirit一部分的应用程序</a></strong></li>
 </ul>
-<p><b> <a name="scanner_business" id="scanner_business"></a> The Scanner Business</b></p>
-<p><font color="#FF0000">Question:</font> Why doesn't this compile?</p>
-<pre><code><font color="#000000"><span class=special> </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>r </span><span class=special>= /*...*/; -</span> <span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>); </span><span class=comment>// BAD [attempts phrase level parsing]</span></font></code></pre> +<p><b> <a name="scanner_business" id="scanner_business"></a> The Scanner Business 扫描器事务</b></p> +<p><font color="#ff0000">Question:</font> Why doesn't this compile?<br><font color="#ff0000">问题:</font>为什么以下程序不能编译?</p> +<pre><code><font color="#000000"><span class="special"> </span><span class="identifier">rule</span><span class="special">&lt;&gt; </span><span class="identifier">r </span><span class="special">= /*...*/;<br></span> <span class="identifier">parse</span><span class="special">(</span><span class="string">"hello world"</span><span class="special">, </span><span class="identifier">r</span><span class="special">, </span><span class="identifier">space_p</span><span class="special">); </span><span class="comment">// BAD [attempts phrase level parsing]</span></font></code></pre> <p>But if I <font color="#000000">remove the skip-parser, everything goes back
-  to normal again:<code></code></font></p>
-<pre><code><font color="#000000"> <span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>r </span><span class=special>= *</span><span class=identifier>anychar_p</span><span class=special>; - </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>); </span><span class=comment>// OK [character level parsing]</span></font></code></pre> + to normal again:</font><br>但如果去掉<font color="#000000">跳读分析器,则 一切又恢复正常:<code></code></font></p> +<pre><code><font color="#000000"> <span class="identifier">rule</span><span class="special">&lt;&gt; </span><span class="identifier">r </span><span class="special">= *</span><span class="identifier">anychar_p</span><span class="special">;<br> </span><span class="identifier">parse</span><span class="special">(</span><span class="string">"hello world"</span><span class="special">, </span><span class="identifier">r</span><span class="special">); </span><span class="comment">// OK [character level parsing]</span></font></code></pre> <p>Sometimes you'll want to pass in a rule to one of the functions parse functions that Spirit provides. The problem is that the rule is a template class that is parameterized by the scanner type. This is rather awkward but unavoidable: <strong>the rule is tied to a scanner</strong>. What's not obvious is that this scanner must be compatible with the scanner that is ultimately passed to the
-  rule's parse member function. Otherwise, the compiler will complain. </p>
+ rule's parse member function. Otherwise, the compiler will complain.<br>有时,你想将一个规则传入某个由Spirit提供的 parse&nbsp;函数。问 题是,规则是一个模板类,它以扫描器类型为参数。这是尴尬而不可避免 的:<strong>规则被绑定至某个扫描器</strong>。有一点不太明显,即这个扫描器必 须兼容于最终传递给该规则的 parse 成员函数的扫描器。否则,编译器将会抗议。 </p> <p>Why does the first call to parse not compile? Because of scanner incompatibility. Behind the scenes, the free parse function creates a scanner from the iterators passed in. In the first call to parse, the scanner created is a plain vanilla
@@ -62,151 +58,126 @@
<tt>rule&lt;&gt;</tt> [see default template parameters of <a href="rule.html">the rule</a>]. The second call creates a scanner of type <tt><a href="scanner.html#phrase_scanner_t">phrase_scanner_t</a></tt>. Thus, in order for the second call to succeed, the rule must be parameterized
-  as <tt>rule&lt;phrase_scanner_t&gt;</tt>:</p>
-<pre><code><font color="#000000"><span class=comment> </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>r </span><span class=special>= </span><span class=special>*</span><span class=identifier>anychar_p</span><span class=special>; - </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, </span><span class=identifier>r</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>); </span><span class=comment>// OK [phrase level parsing]</span></font></code></pre> + as <tt>rule&lt;phrase_scanner_t&gt;</tt>:<br>为什么第一个对 parse 的调用 不能编译?因为扫描器不兼容。在其表象之后,这个 parse 函数从传入的迭代器构造 一个扫描器。在第一个对 parse 的调用中,创建的扫描器是一个普通的
+  <tt>scanner&lt;&gt;</tt>。它兼容于
+ <tt>rule&lt;&gt;</tt> 的缺省扫描器类型[请见 <a href="rule.html">规则</a> 的缺省模板参数]。而第二个调用则创建一个类型为 <tt><a href="scanner.html#phrase_scanner_t">phrase_scanner_t</a></tt> 的扫描器。因 此,为了第二次调用的成功,该规则必须被参数化为 <tt>rule&lt;phrase_scanner_t&gt;</tt>:</p> +<pre><code><font color="#000000"><span class="comment"> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">phrase_scanner_t</span><span class="special">&gt; </span><span class="identifier">r </span><span class="special">= </span><span class="special">*</span><span class="identifier">anychar_p</span><span class="special">;<br> </span><span class="identifier">parse</span><span class="special">(</span><span class="string">"hello world"</span><span class="special">, </span><span class="identifier">r</span><span class="special">, </span><span class="identifier">space_p</span><span class="special">); </span><span class="comment">// OK [phrase level parsing]</span></font></code></pre> <p>Take note however that <tt>phrase_scanner_t</tt> is compatible only when you are using <tt>char const*</tt> iterators and <tt>space_p</tt> as the skip parser. Other than that, you'll have to find the right type of scanner. This is tedious to do correctly. In light of this issue, <strong>it is best to avoid rules as arguments to the parse functions</strong>. Keep in mind that this happens only with rules. The rule is the only parser that has to be tied to a particular
-  scanner type. For instance:</p>
-<pre><span class=comment> </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, *</span><span class=identifier>anychar_p</span><span class=special>); </span><span class=comment><code><font color="#000000"><span class=comment>// OK [character level parsing]</span></font></code> - </span><span class=identifier>parse</span><span class=special>(</span><span class=string>"hello world"</span><span class=special>, *</span><span class=identifier>anychar_p</span><span class=special>, </span><span class=identifier>space_p</span><span class=special>); </span><span class="comment">// OK [phrase level parsing]</span></pre>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"> <strong><img src="theme/note.gif" width="16" height="16">
-      Multiple Scanner Support</strong><br>
+ scanner type. For instance:<br>不过请注意,<tt>phrase_scanner_t</tt> 仅当 你使用 <tt>char const*</tt> 迭代器并以 <tt>space_p</tt> 作为跳读分析器时是兼 容的。否则,你必须找出扫描器的正确类型。要正确实现是很乏味的。由此问题可 见,<strong>最好避免将规则作为参数传给 parse 函数</strong>。留意,这只发生在 规则上。规则是唯一一种必须绑定至特定扫描器类型的分析器。例如:</p> +<pre><span class="comment"> </span><span class="identifier">parse</span><span class="special">(</span><span class="string">"hello world"</span><span class="special">, *</span><span class="identifier">anychar_p</span><span class="special">); </span><span class="comment"><code><font color="#000000"><span class="comment">// OK [character level parsing]</span></font></code> + </span><span class="identifier">parse</span><span class="special">(</span><span class="string">"hello world"</span><span class="special">, *</span><span class="identifier">anychar_p</span><span class="special">, </span><span class="identifier">space_p</span><span class="special">); </span><span class="comment">// OK [phrase level parsing]</span></pre>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"> <strong><img src="theme/note.gif" height="16" width="16">
+      Multiple Scanner Support 多扫描器支持</strong><br>
       <br>
As of v1.8.0, rules can use one or more scanner types. There are cases, for instance, where we need a rule that can work on the phrase and character levels. Rule/scanner mismatch has been a source of confusion and is the no. 1 <a href="faq.html#scanner_business">FAQ</a>. To address this issue, we now have <a href="rule.html#multiple_scanner_support">multiple scanner
-      support</a>. <br>
-      <br>
- <img src="theme/bulb.gif" width="13" height="18"> See the techniques section + support</a>. <br>截止至 v1.8.0,规则可以使用一个或多个扫描器类型。有 些情况下,例如,当我们需要一个可以工作在短语和字符层面的规则时。规则/扫描器 失配是导致混乱的主要来源,且是首要的 <a href="faq.html#scanner_business">FAQ</a>。为了解决该问题,我们现在有了 <a href="rule.html#multiple_scanner_support">多扫描器支持</a><br> + <img src="theme/bulb.gif" height="18" width="13"> See the techniques section for an <a href="techniques.html#multiple_scanner_support">example</a> of a <a href="grammar.html">grammar</a> using a multiple scanner enabled rule, - <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a></td> + <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a><br><img src="theme/bulb.gif" height="18" width="13">&nbsp;有关多扫描器规则 <a href="grammar.html">语法</a> + 、<a href="scanner.html#lexeme_scanner">lexeme_scanner</a> 和 <a href="scanner.html#as_lower_scanner">as_lower_scanner</a> 的 <a href="techniques.html#multiple_scanner_support">例子</a>,请见"技术"一节。 </td>
   </tr>
-</table>
-<p><b> <a name="left_recursion"></a> Eliminating Left Recursion </b></p>
-<p><font color="#FF0000">Question:</font> I ported a grammar from YACC. It's &quot;kinda&quot;
+</tbody></table>
+<p><b> <a name="left_recursion"></a> Eliminating Left Recursion 消除左递归 </b></p> +<p><font color="#ff0000">Question:</font> I ported a grammar from YACC. It's "kinda" working - the parser itself compiles with no errors. But when I try to parse, - it gives me an &quot;invalid page fault&quot;. I tracked down the problem to
-  this grammar snippet:</p>
-<pre> <span class=identifier>or_expr </span><span class=special>= </span><span class=identifier>xor_expr </span><span class=special>| (</span><span class=identifier>or_expr </span><span class=special>&gt;&gt; </span><span class=identifier>VBAR </span><span class=special>&gt;&gt; </span><span class=identifier>xor_expr</span><span class=special>);</span></pre>
+  it gives me an "invalid page fault". I tracked down the problem to
+ this grammar snippet:<br><font color="#ff0000">问题:</font>我从YACC移植 过来一个语法。它只能"部分"工作 - 分析器本身可通过编译。但是当我尝试分析 时,它给出了一个 "invalid page fault"。我跟踪了该问题,至以下语法片段:</p> +<pre> <span class="identifier">or_expr </span><span class="special">= </span><span class="identifier">xor_expr </span><span class="special">| (</span><span class="identifier">or_expr </span><span class="special">&gt;&gt; </span><span class="identifier">VBAR </span><span class="special">&gt;&gt; </span><span class="identifier">xor_expr</span><span class="special">);</span></pre> <p>What you should do is to eliminate direct and indirect left-recursion. This causes the invalid page fault because the program enters an infinite loop. The code above is good for bottom up parsers such as YACC but not for LL parsers
-  such as Spirit.</p>
+ such as Spirit.<br>你要做的是,消除直接或间接的左递归。它会引起无效页错 误,因为程序陷入了无限循环。以上代码对于象YACC这样的由底而上分析器是好的,而 对于象Spirit这样的LL分析器则非如此。</p>
 <p>This is similar to a rule in Hartmut Kaiser's C
- parser (this should be available for download from <a href="http://spirit.sf.net";>Spirit's site</a> as soon as you read this).</p>
-<pre>
-    <span class=identifier>inclusive_or_expression
- </span><span class=special>= </span><span class=identifier>exclusive_or_expression - </span><span class=special>| </span><span class=identifier>inclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression
-    </span><span class=special>;</span></pre>
-<p><span class=special></span>Transforming left recursion to right recursion,
-  we have:</p>
-<pre>    <span class=identifier>inclusive_or_expression
- </span><span class=special>= </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper
-    </span><span class=special>;
-
-    </span><span class=identifier>inclusive_or_expression_helper
- </span><span class=special>= </span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper
-    </span><span class=special>| </span><span class=identifier>epsilon_p
-    </span><span class=special>;</span></pre>
-<p><span class=special></span>I'd go further. Since:</p>
-<pre> <span class=identifier>r </span><span class=special>= </span><span class=identifier>a </span><span class=special>| </span><span class=identifier>epsilon_p</span><span class=special>;</span></pre>
-<p><span class=special></span>is equivalent to:<span class=special><br>
+ parser (this should be available for download from <a href="http://spirit.sf.net/";>Spirit's site</a> as soon as you read this).<br>这类似于 Hartmut Kaiser 的 C + 分析器中的一个规则(当你读到这里时,它应该可以由 <a href="http://spirit.sf.net";>Spirit's 站点</a> 下载得到)。</p> +<pre> <span class="identifier">inclusive_or_expression<br> </span><span class="special">= </span><span class="identifier">exclusive_or_expression<br> </span><span class="special">| </span><span class="identifier">inclusive_or_expression </span><span class="special">&gt;&gt; </span><span class="identifier">OR </span><span class="special">&gt;&gt; </span><span class="identifier">exclusive_or_expression<br> </span><span class="special">;</span></pre> +<p><span class="special"></span>Transforming left recursion to right recursion,
+  we have:<br>将左递归转换为右递归,我们有:</p>
+<pre> <span class="identifier">inclusive_or_expression<br> </span><span class="special">= </span><span class="identifier">exclusive_or_expression </span><span class="special">&gt;&gt; </span><span class="identifier">inclusive_or_expression_helper<br> </span><span class="special">;<br><br> </span><span class="identifier">inclusive_or_expression_helper<br> </span><span class="special">= </span><span class="identifier">OR </span><span class="special">&gt;&gt; </span><span class="identifier">exclusive_or_expression </span><span class="special">&gt;&gt; </span><span class="identifier">inclusive_or_expression_helper<br> </span><span class="special">| </span><span class="identifier">epsilon_p<br> </span><span class="special">;</span></pre> +<p><span class="special"></span>I'd go further. Since:<br>更进一步。因 为:</p> +<pre> <span class="identifier">r </span><span class="special">= </span><span class="identifier">a </span><span class="special">| </span><span class="identifier">epsilon_p</span><span class="special">;</span></pre> +<p><span class="special"></span>is equivalent to:<br><span class="special">相当于:<br>
   </span></p>
-<pre> <span class=identifier>r </span><span class=special>= !</span><span class=identifier>a</span><span class=special>;</span></pre>
-<p>we can simplify <tt>inclusive_or_expression_helper</tt> thus:</p>
-<pre>    <span class=identifier>inclusive_or_expression_helper
- </span><span class=special>= !(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; </span><span class=identifier>inclusive_or_expression_helper</span><span class=special>)
-    ;</span></pre>
-<p><span class=special></span>Now, since:</p>
-<pre> <span class=identifier>r </span><span class=special>= !(</span><span class=identifier>a </span><span class=special>&gt;&gt; </span><span class=identifier>r</span><span class=special>);</span></pre>
-<p><span class=special></span>is equivalent to:</p>
-<pre> <span class=identifier>r </span><span class=special>= *</span><span class=identifier>a</span><span class=special>;</span></pre>
-<p><span class=special></span>we have:</p>
-<pre>    <span class=identifier>inclusive_or_expression_helper
- </span><span class=special>= *(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression</span><span class=special>)
-    ;</span></pre>
-<p><span class=special></span>Now simplifying <tt>inclusive_or_expression</tt>
-  fully, we have:</p>
-<pre>    <span class=identifier>inclusive_or_expression
- </span><span class=special>= </span><span class=identifier>exclusive_or_expression </span><span class=special>&gt;&gt; *(</span><span class=identifier>OR </span><span class=special>&gt;&gt; </span><span class=identifier>exclusive_or_expression</span><span class=special>)
-    ;</span></pre>
-<p><span class=special></span>Reminds me of the calculators. So in short:</p> -<pre> <span class=identifier>a </span><span class=special>= </span><span class=identifier>b </span><span class=special>| </span><span class=identifier>a </span><span class=special>&gt;&gt; </span><span class=identifier>op </span><span class=special>&gt;&gt; </span><span class=identifier>b</span><span class=special>;</span></pre> -<p><span class=special></span><span class=identifier>in </span><span class=identifier>pseudo-YACC
-  </span><span class=identifier>is</span><span class=special>:</span></p>
-<pre> <span class=identifier>a </span><span class=special>= </span><span class=identifier>b </span><span class=special>&gt;&gt; *(</span><span class=identifier>op </span><span class=special>&gt;&gt; </span><span class=identifier>b</span><span class=special>);</span></pre> -<p><span class=special></span>in Spirit. What could be simpler? Look Ma, no recursion,
-  just iteration.</p>
-<p><b> <a name="right_associativity" id="right_associativity"></a> Implementing Right Associativity </b></p> -<p> <font color="#FF0000">Question:</font> I tried adding <tt>'^'</tt> as an operator to compute the power to a calculator grammer. The following code +<pre> <span class="identifier">r </span><span class="special">= !</span><span class="identifier">a</span><span class="special">;</span></pre> +<p>we can simplify <tt>inclusive_or_expression_helper</tt> thus:<br>所以我 们可以简化 <tt>inclusive_or_expression_helper</tt> 为:</p> +<pre> <span class="identifier">inclusive_or_expression_helper<br> </span><span class="special">= !(</span><span class="identifier">OR </span><span class="special">&gt;&gt; </span><span class="identifier">exclusive_or_expression </span><span class="special">&gt;&gt; </span><span class="identifier">inclusive_or_expression_helper</span><span class="special">)<br> ;</span></pre>
+<p><span class="special"></span>Now, since:<br>现在,由于:</p>
+<pre> <span class="identifier">r </span><span class="special">= !(</span><span class="identifier">a </span><span class="special">&gt;&gt; </span><span class="identifier">r</span><span class="special">);</span></pre>
+<p><span class="special"></span>is equivalent to:<br>相当于:</p>
+<pre> <span class="identifier">r </span><span class="special">= *</span><span class="identifier">a</span><span class="special">;</span></pre>
+<p><span class="special"></span>we have:<br>我们有:</p>
+<pre> <span class="identifier">inclusive_or_expression_helper<br> </span><span class="special">= *(</span><span class="identifier">OR </span><span class="special">&gt;&gt; </span><span class="identifier">exclusive_or_expression</span><span class="special">)<br> ;</span></pre> +<p><span class="special"></span>Now simplifying <tt>inclusive_or_expression</tt>
+  fully, we have:<br>现在对 <tt>inclusive_or_expression</tt>
+  完全简化,我们有:</p>
+<pre> <span class="identifier">inclusive_or_expression<br> </span><span class="special">= </span><span class="identifier">exclusive_or_expression </span><span class="special">&gt;&gt; *(</span><span class="identifier">OR </span><span class="special">&gt;&gt; </span><span class="identifier">exclusive_or_expression</span><span class="special">)<br> ;</span></pre> +<p><span class="special"></span>Reminds me of the calculators. So in short:<br>记住我们的计算器。所以用伪-YACC可缩写为:</p> +<pre> <span class="identifier">a </span><span class="special">= </span><span class="identifier">b </span><span class="special">| </span><span class="identifier">a </span><span class="special">&gt;&gt; </span><span class="identifier">op </span><span class="special">&gt;&gt; </span><span class="identifier">b</span><span class="special">;</span></pre> +<p><span class="special"></span><span class="identifier">in </span><span class="identifier">pseudo-YACC + </span><span class="identifier">is</span><span class="special">:<br></span><span class="identifier">在Spirit中则 是:</span><span class="special"></span><span class="special"></span></p> +<pre> <span class="identifier">a </span><span class="special">= </span><span class="identifier">b </span><span class="special">&gt;&gt; *(</span><span class="identifier">op </span><span class="special">&gt;&gt; </span><span class="identifier">b</span><span class="special">);</span></pre>
+<p>in Spirit. What could be simpler? Look Ma, no recursion,
+ just iteration.<br><span class="special"></span>还有什么可以更简 单?看,没有递归,只有循环。</p> +<p><b> <a name="right_associativity" id="right_associativity"></a> Implementing Right Associativity 实现右关联 </b></p> +<p> <font color="#ff0000">Question:</font> I tried adding <tt>'^'</tt> as an operator to compute the power to a calculator grammer. The following code<br><font color="#ff0000">问题:</font>我尝试为计算器语法增加一个操作符 <tt>'^'</tt> 以计算幂数。以下代码
 </p>
-<pre>    <span class=identifier>pow_expression
- </span><span class=special>= </span><span class=identifier>pow_operand </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=literal>'^' </span><span class=special>&gt;&gt; </span><span class=identifier>pow_operand </span><span class=special>[ </span><span class=special>&amp; </span><span class=identifier>do_pow </span><span class=special>]
-                      </span><span class=special>)
-    </span><span class=special>;</span>
+<pre> <span class="identifier">pow_expression <br> </span><span class="special">= </span><span class="identifier">pow_operand </span><span class="special">&gt;&gt; </span><span class="special">*( </span><span class="literal">'^' </span><span class="special">&gt;&gt; </span><span class="identifier">pow_operand </span><span class="special">[ </span><span class="special">&amp; </span><span class="identifier">do_pow </span><span class="special">]<br> </span><span class="special">)<br> </span><span class="special">;</span>
 </pre>
-<p>parses the input correctly, but I want the operator to be evalutated from right to left. In other words, the expression <tt>2^3^4</tt> is supposed to have the same semantics as <tt>2^(3^4)</tt> instead of <tt>(2^3)^4</tt>. How do I do it? +<p>parses the input correctly, but I want the operator to be evalutated from right to left. In other words, the expression <tt>2^3^4</tt> is supposed to have the same semantics as <tt>2^(3^4)</tt> instead of <tt>(2^3)^4</tt>. How do I do it?<br>可以正确地分析输入,但是我希望这个操作 符是从右向左求值的。换句话说,表达式 <tt>2^3^4</tt> 应具有与 <tt>2^(3^4)</tt> 相同的语义,而不是 <tt>(2^3)^4</tt>。我要怎么做呢?
 </p>
-<p> The "textbook recipe" for Right Associativity is Right Recursion. In BNF that means: -<pre> &lt;pow_expression&gt; ::= &lt;pow_operand&gt; '^' &lt;pow_expression&gt; | &lt;pow_operand&gt;
-</pre>
-<p>But we better don't take the theory too literally here, because if the first alternative fails, the semantic actions within <tt>pow_operand</tt> might have been executed already and will then be executed again when trying the second alternative. So let's apply Left Factorization to factor out <tt>pow_operand</tt>: -<pre> &lt;pow_expression&gt; ::= &lt;pow_operand&gt; &lt;pow_expression_helper&gt; - &lt;pow_expression_helper&gt; ::= '^' &lt;pow_expression&gt; | <i>&#949;</i>
-</pre>
-<p>The production <tt>pow_expression_helper</tt> matches the empty string <i>&#949;</i>, so we can replace the alternative with the optional operator in Spirit code. +<p> The "textbook recipe" for Right Associativity is Right Recursion. In BNF that means:<br>解决右关联的"教科书方法"是右递归。在BNF中,意味着: +</p><pre> &lt;pow_expression&gt; ::= &lt;pow_operand&gt; '^' &lt;pow_expression&gt; | &lt;pow_operand&gt;<br></pre> +<p>But we better don't take the theory too literally here, because if the first alternative fails, the semantic actions within <tt>pow_operand</tt>
+might have been executed already and will then be executed again when
+trying the second alternative. So let's apply Left Factorization to
+factor out <tt>pow_operand</tt>:<br>但我们最好不要过于从字面理解这个理 论,因为如果第一个选择失败,那么 <tt>pow_operand</tt> +内的语义动作可能已经被执行,而在尝试第二个选择时可能会被再次执行。因此,我 们应用左分解来实现 <tt>pow_operand</tt>: +</p><pre> &lt;pow_expression&gt; ::= &lt;pow_operand&gt; &lt;pow_expression_helper&gt;<br> &lt;pow_expression_helper&gt; ::= '^' &lt;pow_expression&gt; | <i>ε</i> <br></pre> +<p>The production <tt>pow_expression_helper</tt> matches the empty string <i>ε</i>, so we can replace the alternative with the optional operator in Spirit code.<br>工具 <tt>pow_expression_helper</tt> 匹配空字符串 <i>ε</i>, 因此我们在Spirit代码中可以用可选操作符来替换这一选择。
 </p>
-<pre>    <span class=identifier>pow_expression
- </span><span class=special>= </span><span class=identifier>pow_operand </span><span class=special>&gt;&gt; </span><span class=special>!( </span><span class=literal>'^' </span><span class=special>&gt;&gt; </span><span class=identifier>pow_expression </span><span class=special>[ </span><span class=special>&amp; </span><span class=identifier>do_pow </span><span class=special>]
-                      </span><span class=special>)
-    </span><span class=special>;</span>
+<pre> <span class="identifier">pow_expression <br> </span><span class="special">= </span><span class="identifier">pow_operand </span><span class="special">&gt;&gt; </span><span class="special">!( </span><span class="literal">'^' </span><span class="special">&gt;&gt; </span><span class="identifier">pow_expression </span><span class="special">[ </span><span class="special">&amp; </span><span class="identifier">do_pow </span><span class="special">]<br> </span><span class="special">)<br> </span><span class="special">;</span>
 </pre>
-<p>Now any semantic actions within <tt>pow_operand</tt> can safely be executed. For stack-based evaluation that means that each match of <tt>pow_operand</tt> will leave one value on the stack and the recursion makes sure there are (at least) two values on the stack when <tt>do_pow</tt> is fired to reduce these two values to their power. +<p>Now any semantic actions within <tt>pow_operand</tt> can safely be executed. For stack-based evaluation that means that each match of <tt>pow_operand</tt> will leave one value on the stack and the recursion makes sure there are (at least) two values on the stack when <tt>do_pow</tt> is fired to reduce these two values to their power.<br>现在 <tt>pow_operand</tt> 内的任何语义动作均可安全执行。对于基于栈的求值,这意味 着 <tt>pow_operand</tt> 的每次匹配将留下一个值在栈中,且这个递归将确保当 <tt>do_pow</tt> 被触发时栈中(至少)有两个值,通过这两个值计算得到它们的幂。
 </p>
-<p>In cases where this technique isn't applicable, such as C-style assignment
-<pre>    <span class=identifier>assignment
- </span><span class=special>= </span><span class=identifier>lvalue </span><span class=special>&gt;&gt; </span><span class=literal>'=' </span><span class=special>&gt;&gt; </span><span class=identifier>assignment - </span><span class=special>| </span><span class=identifier>ternary_conditional
-    </span><span class=special>;</span>
+<p>In cases where this technique isn't applicable, such as C-style assignment<br>某些情况下这种技术并不适用,如在C-风格的赋值中 +</p><pre> <span class="identifier">assignment<br> </span><span class="special">= </span><span class="identifier">lvalue </span><span class="special">&gt;&gt; </span><span class="literal">'=' </span><span class="special">&gt;&gt; </span><span class="identifier">assignment <br> </span><span class="special">| </span><span class="identifier">ternary_conditional <br> </span><span class="special">;</span>
 </pre>
-<p>you can append <tt>| epsilon_p [ <i>action</i> ] &gt;&gt; nothing_p</tt> to a parser to correct the semantic context when backtracking occurs (in the example case that would be dropping the address pushed by <tt>lvalue</tt> off the evaluation stack):
+<p>you can append <tt>| epsilon_p [ <i>action</i> ] &gt;&gt; nothing_p</tt>
+to a parser to correct the semantic context when backtracking occurs
+(in the example case that would be dropping the address pushed by <tt>lvalue</tt> off the evaluation stack):<br>你可以往分析器中增加 <tt>| epsilon_p [ <i>action</i> ] &gt;&gt; nothing_p</tt>,以更正回溯发生时的语义 语境(在此例中,将把由<tt>lvalue</tt> 压入的地址从求值栈中删除):
 </p>
-<pre>    <span class=identifier>assignment
- </span><span class=special>= </span><span class=identifier>lvalue </span><span class=special>&gt;&gt; </span><span class=special>( </span><span class=literal>'=' </span><span class=special>&gt;&gt; </span><span class=identifier>assignment </span></span><span class=special>[ </span><span class=special>&amp; </span><span class=identifier>do_store </span><span class=special>] - </span><span class=special>| </span><span class=identifier>epsilon_p </span><span class=special>[ </span><span class=special>&amp; </span><span class=identifier>do_drop </span><span class=special>] - </span><span class=special>&gt;&gt; </span><span class=identifier>nothing_p
-                </span><span class=special>)
- </span><span class=special>| </span><span class=identifier>ternary_conditional
-    </span><span class=special>;</span>
+<pre> <span class="identifier">assignment<br> </span><span class="special">= </span><span class="identifier">lvalue </span><span class="special">&gt;&gt; </span><span class="special">( </span><span class="literal">'=' </span><span class="special">&gt;&gt; </span><span class="identifier">assignment </span><span class="special">[ </span><span class="special">&amp; </span><span class="identifier">do_store </span><span class="special">]<br> </span><span class="special">| </span><span class="identifier">epsilon_p </span><span class="special">[ </span><span class="special">&amp; </span><span class="identifier">do_drop </span><span class="special">]<br> </span><span class="special">&gt;&gt; </span><span class="identifier">nothing_p<br> </span><span class="special">) <br> </span><span class="special">| </span><span class="identifier">ternary_conditional <br> </span><span class="special">;</span>
 </pre>
-<p>However, this trick compromises the clear separation of syntax and semantics, so you also might want to consider using an <a href="trees.html">AST</a> instead of semantic actions so you can just go with the first definition of <tt>assignment</tt>. +<p>However, this trick compromises the clear separation of syntax and semantics, so you also might want to consider using an <a href="trees.html">AST</a> instead of semantic actions so you can just go with the first definition of <tt>assignment</tt>.<br>然而,这种方法是以语法 与语义的清晰分离为代价的,所以你也可能会考虑使用 <a href="trees.html">AST</a> 来替代语义动作,这样你可以只需要 <tt>assignment</tt> 的第一个定义。
 </p>
<p><b> <a name="lexeme_and_rules" id="lexeme_and_rules"></a> The lexeme_d directive
-  and rules</b></p>
-<p> <font color="#FF0000">Question:</font> Does lexeme_d not support expressions - which include rules? In the example below, the definition of atomicRule compiles,
+  and rules &nbsp; lexeme_d指示符与规则</b></p>
+<p> <font color="#ff0000">Question:</font> Does lexeme_d not support expressions + which include rules? In the example below, the definition of atomicRule compiles,<br><font color="#ff0000">问题:</font>lexeme_d 不支持含有规则的表 达式吗?在以下例子中,atomicRule 的定义可以编译,
 </p>
-<pre> <span class=identifier></span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>atomicRule</span> - <span class=special>= </span><span class=identifier>lexeme_d</span><span class=special>[(</span><span class=identifier>alpha_p </span><span class=special>| </span><span class=literal>'_'</span><span class=special>) &gt;&gt; *(</span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>)];</span></pre> +<pre> <span class="identifier"></span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">phrase_scanner_t</span><span class="special">&gt; </span><span class="identifier">atomicRule</span> + <span class="special">= </span><span class="identifier">lexeme_d</span><span class="special">[(</span><span class="identifier">alpha_p </span><span class="special">| </span><span class="literal">'_'</span><span class="special">) &gt;&gt; *(</span><span class="identifier">alnum_p </span><span class="special">| </span><span class="literal">'.' </span><span class="special">| </span><span class="literal">'-' </span><span class="special">| </span><span class="literal">'_'</span><span class="special">)];</span></pre> <p>but if I move <tt>alnum_p | '.' | '-' | '_'</tt> into its own rule, the compiler complains about conversion from <tt>const scanner&lt;...&gt;</tt> to <tt>const
-  phrase_scaner_t&amp;</tt>. </p>
-<pre> <span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>ch </span><span class=special> - = </span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>;</span>
-
-<span class=identifier> rule</span><span class=special>&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt; </span><span class=identifier>compositeRule</span> - <span class=special>= </span><span class=identifier>lexeme_d</span><span class=special>[(</span><span class=identifier>alpha_p </span><span class=special>| </span><span class=literal>'_'</span><span class=special>) &gt;&gt; *(</span><span class=identifier>ch</span><span class=special>)]; </span><span class="comment">// &lt;- error source</span></pre> + phrase_scaner_t&amp;</tt>.<br>不过,如果我将 <tt>alnum_p | '.' | '-' | '_'</tt> 移入它的规则中,编译器就会对从 <tt>const scanner&lt;...&gt;</tt> 到 <tt>const
+  phrase_scaner_t&amp;</tt> 的转化提出异议。 </p>
+<pre> <span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">phrase_scanner_t</span><span class="special">&gt; </span><span class="identifier">ch </span><span class="special"> + = </span><span class="identifier">alnum_p </span><span class="special">| </span><span class="literal">'.' </span><span class="special">| </span><span class="literal">'-' </span><span class="special">| </span><span class="literal">'_'</span><span class="special">;</span>
+
+<span class="identifier"> rule</span><span class="special">&lt;</span><span class="identifier">phrase_scanner_t</span><span class="special">&gt; </span><span class="identifier">compositeRule</span> + <span class="special">= </span><span class="identifier">lexeme_d</span><span class="special">[(</span><span class="identifier">alpha_p </span><span class="special">| </span><span class="literal">'_'</span><span class="special">) &gt;&gt; *(</span><span class="identifier">ch</span><span class="special">)]; </span><span class="comment">// &lt;- error source</span></pre> <p>You might get the impression that the <tt>lexeme_d</tt> directive and rules do not mix. Actually, this problem is related to the first FAQ entry: The Scanner Business. More precisely, the <tt>lexeme_d</tt> directive and rules with incompatible
@@ -214,96 +185,102 @@
incompatibility is the directive itself. The <tt>lexeme_d</tt> directive transforms the scanner it receives into something that disables the skip parser. This non-skipping scanner, unfortunately, is incompatible with the original scanner before transformation
-  took place.</p>
+ took place.<br>你可能有这样的印象,<tt>lexeme_d</tt> 指示符和规则不能混 用。实际上,这个问题与第一个FAQ:扫描器事务,是相关的。更准确地 说,<tt>lexeme_d</tt> 指示符与带有不兼容扫描器类型的规则不能混用。这个问题更 为微妙。导致扫描器不兼容的就是这个指示符本身。<tt>lexeme_d</tt> 指示符将所接 受的扫描器转换为禁止了跳读分析器的某种类型。很不幸,这个无跳读的扫描器与转换 之前的原扫描器是不兼容的。</p> <p>The simplest solution is not to use rules in the <tt>lexeme_d</tt>. Instead, you can definitely apply <tt>lexeme_d</tt> to subrules and grammars if you really need more complex parsers inside the <tt>lexeme_d</tt>. If you really must use a rule, you need to know the exact scanner used by the directive. The <tt>lexeme_scanner</tt> metafunction is your friend here. The example above will work as expected once
-  we give the <tt>ch</tt> rule a correct scanner type:</p>
-<pre> <span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>lexeme_scanner</span><span class="special">&lt;</span><span class=identifier>phrase_scanner_t</span><span class=special>&gt;::</span><span class="identifier">type</span><span class=special>&gt; </span><span class=identifier>ch </span><span class=special> - = </span><span class=identifier>alnum_p </span><span class=special>| </span><span class=literal>'.' </span><span class=special>| </span><span class=literal>'-' </span><span class=special>| </span><span class=literal>'_'</span><span class=special>;</span></pre> -<p>Note: make sure to add &quot;<tt>typename</tt>&quot; before <tt>lexeme_scanner</tt>
-  when this is used inside a template class or function.</p>
+ we give the <tt>ch</tt> rule a correct scanner type:<br>最简单的解决方法 是,不要在 <tt>lexeme_d</tt> 中使用规则。如果你真的需要在 <tt>lexeme_d</tt> 中使用较复杂的分析器,你可以明确地将 <tt>lexeme_d</tt> 应用于子规则和语法。 此时,<tt>lexeme_scanner</tt> + 元函数可以帮忙。上述例子可以正确工作,只要我们给定 <tt>ch</tt> 规则一个正 确的扫描器类型:</p> +<pre> <span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">lexeme_scanner</span><span class="special">&lt;</span><span class="identifier">phrase_scanner_t</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt; </span><span class="identifier">ch </span><span class="special"> + = </span><span class="identifier">alnum_p </span><span class="special">| </span><span class="literal">'.' </span><span class="special">| </span><span class="literal">'-' </span><span class="special">| </span><span class="literal">'_'</span><span class="special">;</span></pre> +<p>Note: make sure to add "<tt>typename</tt>" before <tt>lexeme_scanner</tt> + when this is used inside a template class or function.<br>注意:当被用于 模板类或模板函数内部时,请确认在 <tt>lexeme_scanner</tt>
+  之前加上 "<tt>typename</tt>"。</p>
<p>The same thing happens when rules are used inside the <tt>as_lower_d</tt> directive. - In such cases, you can use the <tt>as_lower_scanner</tt>. See the <span class=identifier><tt><a href="scanner.html#lexeme_scanner">lexeme_scanner</a></tt></span> - and <tt><a href="scanner.html#as_lower_scanner">as_lower_scanner</a></tt>.</p>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"><img src="theme/bulb.gif" width="13" height="18"> See + In such cases, you can use the <tt>as_lower_scanner</tt>. See the <span class="identifier"><tt><a href="scanner.html#lexeme_scanner">lexeme_scanner</a></tt></span> + and <tt><a href="scanner.html#as_lower_scanner">as_lower_scanner</a></tt>.<br>在 <tt>as_lower_d</tt> 指示符内使用规则时,也会发生同样的事情。此时,你可以使 用 <tt>as_lower_scanner</tt>。请见 <span class="identifier"><tt><a href="scanner.html#lexeme_scanner">lexeme_scanner</a></tt></span> 和 <tt><a href="scanner.html#as_lower_scanner">as_lower_scanner</a></tt>。</p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><img src="theme/bulb.gif" height="18" width="13"> See the techniques section for an <a href="techniques.html#multiple_scanner_support">example</a> of a <a href="grammar.html">grammar</a> using a <a href="rule.html#multiple_scanner_support">multiple scanner enabled rule,</a> <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> - and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a></td> + and <a href="scanner.html#as_lower_scanner">as_lower_scanner.</a><br><img src="theme/bulb.gif" height="18" width="13"> 有关使用 <a href="rule.html#multiple_scanner_support">multiple + scanner enabled rule </a><a href="grammar.html">语法</a><a href="rule.html#multiple_scanner_support">,</a> <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> 和 <a href="scanner.html#as_lower_scanner">as_lower_scanner</a> 的 <a href="techniques.html#multiple_scanner_support">例子</a>,请参见"技术"一节。 <a href="scanner.html#as_lower_scanner"></a></td>
   </tr>
-</table>
-<p><strong><a name="kleene_star"></a>Kleene Star infinite loop</strong></p>
-<p><font color="#FF0000">Question</font>: Why Does This Loop Forever?</p>
-<pre> <span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>optional </span><span class=special>= !(</span>str_p<span class="special">(</span><span class="string">&quot;optional&quot;</span><span class="special">)); - </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class="identifier">list_of_optional </span><span class=special>= *</span><span class=identifier>optional</span><span class="special">;</span></pre>
+</tbody></table>
+<p><strong><a name="kleene_star"></a>Kleene Star infinite loop 克林星无限循 环</strong></p> +<p><font color="#ff0000">Question</font>: Why Does This Loop Forever?<br><font color="#ff0000">问题:</font>为何以下例子会无限循环?</p> +<pre> <span class="identifier">rule</span><span class="special">&lt;&gt; </span><span class="identifier">optional </span><span class="special">= !(</span>str_p<span class="special">(</span><span class="string">"optional"</span><span class="special">));<br> </span><span class="identifier">rule</span><span class="special">&lt;&gt; </span><span class="identifier">list_of_optional </span><span class="special">= *</span><span class="identifier">optional</span><span class="special">;</span></pre> <p>The problem with this is that the kleene star will continue looping until it gets a no-match from it's enclosed parser. Because the <tt>optional</tt> rule is optional, it will always return a match. Even if the input doesn't match - &quot;optional&quot; it will return a zero length match. <tt>list_of_optional</tt>
+  "optional" it will return a zero length match. <tt>list_of_optional</tt>
will keep calling optional forever since optional will never return a no-match. - So in general, any rule that can be &quot;nullable&quot; (meaning it can return
-  a zero length match) must not be put inside a kleene star.</p>
+  So in general, any rule that can be "nullable" (meaning it can return
+ a zero length match) must not be put inside a kleene star.<br>这里的问题 是,克林星会持续地循环,直至它从内嵌分析器中获得一个不匹配。因为 <tt>optional</tt> 规则是可选的,它总是返回匹配。即使输入并不匹 配 "optional",它还是会返回一个零长度的匹配。<tt>list_of_optional</tt> + 将不停地调用 optional,由于 optional 永远不会返回一个不匹配。所以一般来 说,任何可能为 "nullable" (即可以返回零长度匹配)的规则都不能置于克林星之内。 </p>
 <p><strong><a name="CVS"></a>Boost CVS and Spirit CVS</strong></p>
-<p><font color="#FF0000">Question:</font> There is Boost CVS and Spirit CVS. Which
-  is used for further development of Spirit?</p>
+<p><font color="#ff0000">Question:</font> There is Boost CVS and Spirit CVS. Which + is used for further development of Spirit?<br><font color="#ff0000">问 题:</font>现在既有 Boost CVS 又有 Spirit CVS。Spirit 后续的开发将使用哪一 个?</p> <p> Generally, development takes place in Spirit's CVS. However, from time to time a new version of Spirit will be integrated in Boost. When this happens development takes place in the Boost CVS. There will be announcements on the
-  Spirit mailing lists whenever the status of the Spirit CVS changes.<br>
+ Spirit mailing lists whenever the status of the Spirit CVS changes.<br>通 常,开发是在Spirit的CVS中进行的。但是,时不时要将Spirit的新版本集成到 Boost中。这时就需要在Boost CVS中进行开发了。当Spirit CVS的状态改变时,在 Spirit邮件列表中会有通知。<br>
 </p>
-<table width="80%" border="0" align="center">
-  <tr>
-    <td class="note_box"><img src="theme/alert.gif" width="16" height="16">
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+    <td class="note_box"><img src="theme/alert.gif" height="16" width="16">
During development of Spirit v1.8.1 (released as part of boost-1.32.0) and
     v1.6.2, Spirit's developers decided to stop maintaining Spirit CVS for
BRANCH_1_8 and BRANCH_1_6. This was necessary to reduce the added work of maintaining and synch'ing two repositories. The maintenance of these branches will take place on Boost CVS. At this time, new developments towards Spirit
     v2 and other experimental developments are expected to happen in Spirit
-    CVS.</td>
+    CVS.<br><img src="theme/alert.gif" height="16" width="16">
+    在Spirit v1.8.1 (作为boost-1.32.0的组成部分发布)和
+    v1.6.2 的开发期间,Spirit的开发者决定停止为
+ BRANCH_1_8 和 BRANCH_1_6 维护Spirit CVS。为了减少维护和同步两个版本库的 工作量,这是必须的。这些分支的维护将在Boost CVS中进行。此时,Spirit
+    v2的新开发以及其它试验性质的开发工作仍在Spirit
+    CVS中。</td>
   </tr>
-</table>
+</tbody></table>
<p><strong><a name="compilation_times"></a>How to reduce compilation times with
-  complex Spirit grammars </strong></p>
-<p><font color="#FF0000">Question:</font> Are there any techniques to minimize
+  complex Spirit grammars 如何减少复杂的Spirit语法的编译时间 </strong></p>
+<p><font color="#ff0000">Question:</font> Are there any techniques to minimize compile times using spirit? For simple parsers compile time doesn't seem to
   be a big issue, but recently I created a parser with about 78 rules
and it took about 2 hours to compile. I would like to break the grammar up into smaller chunks, but it is not as easy as I thought it would be because rules - in two grammar capsules are defined in terms of each other. Any thoughts?</p>
-<p> The only way to reduce compile times is </p>
+ in two grammar capsules are defined in terms of each other. Any thoughts?<br><font color="#ff0000">问题:</font>有 +没有什么技术可以最小化使用spirit的编译时间?对于较为简单的分析器,编译时间 不是什么大的问题,但最近我创建了一个约有78个规则的分析器,它差 +不多需要2小时才编译完。我很想将此语法分解为小块,但这并非我所想的那么容 易,因为分在两个语法中的规则要相互根据对方来定义。有别的方法吗?</p> +<p> The only way to reduce compile times is<br>减少编译时间的唯一方法是 </p>
 <ul>
-  <li> to split up your grammars into smaller chunks</li>
+ <li> to split up your grammars into smaller chunks<br>将你的语法分为更小 的块</li> <li> prevent the compiler from seeing all grammar definitions at the same time
-    (in the same compilation unit)</li>
+ (in the same compilation unit)<br>阻止编译器在同一时间(在同一个编译单元 中)看到所有的语法定义</li>
 </ul>
-<p>The first task is merely logistical, the second is rather a technical one. </p> +<p>The first task is merely logistical, the second is rather a technical one.<br>第一项任务很明显,第二项才是技术活。 </p> <p>A good example of solving the first task is given in the Spirit cpp_lexer example - written by JCAB (you may find it on the <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php";>applications' repository</a>). + written by JCAB (you may find it on the <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php";>applications' repository</a>).<br>由JCAB编写的Spirit cpp_lexer 例子中给出了解决第一项任务 的一个好例子(你可以在 <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php";>应 用程序仓库</a> 中找到它)。
 </p>
<p>The cross referencing problems may be solved by some kind of forward declaration, or, if this does not work, by introducing some dummy template argument to the non-templated grammars. Thus allows the instantiation time to be defered until the
-  compiler has seen all the defintions:</p>
-<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br> grammar2;</p>
-
- <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br> <span class="keyword">struct</span> grammar1 : <span class="keyword">public</span> grammar&lt;grammar1&gt;<br> {
-    <span class="comment">// refers to grammar2&lt;&gt;</span>
+ compiler has seen all the defintions:<br>交叉引用的问题可以通过一些前向声 明来解决,或者,如果这样不行的话,也可以通过向非模板语法引入一些伪模板参数来 解决。这样可以将实例化时间推迟至编译器见到所有定义为止:</p> +<pre> <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br> grammar2;
+
+ <span class="keyword">template</span> &lt;<span class="keyword">typename</span> T = <span class="keyword">int</span>&gt;<br> <span class="keyword">struct</span> grammar1 : <span class="keyword">public</span> grammar&lt;grammar1&gt;<br> {<br> <span class="comment">// refers to grammar2&lt;&gt; 引用grammar2&lt;&gt;</span>
     };

-    <span class="keyword">template</span> &lt;typename T&gt;
- <span class="keyword">struct</span> grammar2 : <span class="keyword">public</span> grammar&lt;grammar2&gt;
-    {
-    <span class="comment">// refers to grammar1&lt;&gt;</span>
+ <span class="keyword">template</span> &lt;typename T&gt;<br> <span class="keyword">struct</span> grammar2 : <span class="keyword">public</span> grammar&lt;grammar2&gt;<br> {<br> <span class="comment">// refers to grammar1&lt;&gt; 引用grammar1&lt;&gt;</span>
     };

     //...
- grammar1&lt;&gt; g; <span class="comment">// both grammars instantiated here</span> + grammar1&lt;&gt; g; <span class="comment">// both grammars instantiated here 两个语法均在此实例化</span>
 </pre>
<p>The second task is slightly more complex. You must ensure that in the first compilation unit the compiler sees only some function/template <strong>declaration</strong>
@@ -312,17 +289,19 @@
you need to manually (explicitly) instantiate these templates with the correct template parameters inside a separate compilation unit. This way the compilation
   time is split between several compilation units, reducing the overall
-  required time drastically too. </p>
+ required time drastically too.<br>第二个任务要复杂些。你必须确保在第一个 编译单元中编译器只见到一些函数/模板的<strong>声明</strong>,而在第二个编译单 元中是函数/模板的<strong>定义</strong>。如果没有涉及模板,这没有问题。如果涉 及到模板,你就需要手工(显式)地在各个编译单元中以正确的模板参数实例化这些模 板。使用这种方法,编译时间被几个编译单元分割,从而大大减少所需的总时间。 </p> <p>For a sample, showing how to achieve this, you may want to look at the <tt>Wave</tt> - preprocessor library, where this technique is used extensively. (this should be available for download from <a href="http://spirit.sf.net";>Spirit's site</a> as soon as you read this).</p> -<p><strong><a name="frame_assertion" id="frame_assertion"></a>Closure frame assertion</strong></p> -<p><font color="#FF0000">Question:</font> When I run the parser I get an assertion - <span class="string">&quot;frame.get() != 0 in file closures.hpp&quot;</span>.
-  What am I doing wrong?</p>
+ preprocessor library, where this technique is used extensively. (this should be available for download from <a href="http://spirit.sf.net/";>Spirit's site</a> as soon as you read this).<br>作为一个示范如何实现这一点的例子,你可以看一下 <tt>Wave</tt> + 预处理器库,其中广泛使用了此技术(在你阅读本文时,该库应可从 <a href="http://spirit.sf.net";>Spirit's 站点</a> 开载了)。</p> +<p><strong><a name="frame_assertion" id="frame_assertion"></a>Closure frame assertion 闭包帧断言</strong></p> +<p><font color="#ff0000">Question:</font> When I run the parser I get an assertion
+  <span class="string">"frame.get() != 0 in file closures.hpp"</span>.
+ What am I doing wrong?<br><font color="#ff0000">问题:</font>当我运行一个 分析器时,获得了一个 + <span class="string">"frame.get() != 0 in file closures.hpp"</span> 的断 言。我做错了什么?</p> <p>Basically, the assertion fires when you are accessing a closure variable that is not constructed yet. Here's an example. We have three rules <tt>a</tt>, <tt>b</tt> and <tt>c</tt>. Consider that the rule <tt>a</tt> has a closure member <tt>m</tt>.
-  Now:</p>
+ Now:<br>基本上,这个断言在你访问一个尚未构造的闭包变量时触发。以下是一个 例子。我们有三个规则 <tt>a</tt>, <tt>b</tt> 和 <tt>c</tt>。假设规则 <tt>a</tt> 有一个闭包成员 <tt>m</tt>。现在:</p> <pre> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span> <span class="identifier">b</span> <span class="special">=</span> <span class="identifier">int_p</span><span class="special">[</span><span class="identifier">a</span><span class="special">.</span><span class="identifier">m</span> <span class="special">=</span> 123<span class="special">];</span> <span class="identifier">c</span> <span class="special">=</span> <span class="identifier">b</span><span class="special">;</span></pre>
@@ -332,40 +311,44 @@
<tt>m</tt>. On the other hand, when <tt>c</tt> is invoked, and <tt>c</tt> attempts to call <tt>b</tt>, no frame for <tt>a</tt> is set. Thus, when <tt>b</tt> is called from <tt>c</tt>, the semantic action <tt>[a.m = 123]</tt>will fire the - <span class="string">&quot;frame.get() != 0 in file closures.hpp&quot;</span>
-  assertion.</p>
-<p><strong><a name="greedy_rd" id="greedy_rd"></a>Greedy RD</strong></p>
-<p><font color="#FF0000">Question:</font> I'm wondering why the this won't work
-  when parsed:</p>
-<pre>
-<span class="identifier"> a</span> <span class="special">= +</span><span class="identifier">anychar_p</span><span class="special">;</span>
+  <span class="string">"frame.get() != 0 in file closures.hpp"</span>
+  assertion.<br>当规则 <tt>a</tt> 被调用时,它的帧被设置,其中含有它的成员
+  <tt>m</tt>。因此,当从 <tt>a</tt> 调用 <tt>b</tt> 时,语义动作<tt></tt>
+  <tt>[a.m = 123]</tt>将把 <tt>123</tt> 保存在 <tt>a</tt> 的闭包成员
+ <tt>m</tt> 中。另一方面,当 <tt>c</tt> 被调用且 <tt>c</tt> 试图调用 <tt>b</tt> 时,并没有为 <tt>a</tt> 设置帧。因此,当从 <tt>c</tt> 调用 <tt>b</tt>&nbsp;<tt></tt>时,语义动作 <tt>[a.m = 123]</tt>将触发
+  <span class="string">"frame.get() != 0 in file closures.hpp"</span>
+  断言。</p>
+<p><strong><a name="greedy_rd" id="greedy_rd"></a>Greedy RD &nbsp;贪心 RD</strong></p> +<p><font color="#ff0000">Question:</font> I'm wondering why the this won't work + when parsed:<br><font color="#ff0000">问题:</font>我很奇怪为什么在进行分 析时,以下语法不能工作:</p> +<pre><span class="identifier"> a</span> <span class="special">= +</span><span class="identifier">anychar_p</span><span class="special">;</span> <span class="identifier">b</span> = <span class="string">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="string">')'</span><span class="special">;</span></pre>
-<p>Try this:</p>
-<pre>
-<span class="identifier"> a</span> <span class="special">= +(</span><span class="identifier">anychar_p - </span><span class="string">')'</span><span class="special">);</span>
+<p>Try this:<br>试一下这个:</p>
+<pre><span class="identifier"> a</span> <span class="special">= +(</span><span class="identifier">anychar_p - </span><span class="string">')'</span><span class="special">);</span> <span class="identifier">b</span> <span class="special">=</span> <span class="string">'('</span> <span class="special">&gt;&gt;</span> <span class="identifier">a</span> <span class="special">&gt;&gt;</span> <span class="string">')'</span><span class="special">;</span></pre> <p>David Held writes: That's because it's like the langoliers--it eats everything up. You usually want to say what it shouldn't eat up by subtracting the terminating character from the parser. The moral being: Using <tt>*anychar_p</tt> or <tt>+anychar_p</tt>
-  all by itself is usually a <em>Bad Thing</em>&#8482;.</p>
+ all by itself is usually a <em>Bad Thing</em>™.<br>David Held 写道:这是 因为它象langoliers--它把一切都吃掉了。通常你想通过从分析器中去掉一些终止符来 说明分析器不应吃掉什么。规则是:使用 <tt>*anychar_p</tt> 或 <tt>+anychar_p</tt>
+  通常是一件坏事。</p>
<p>In other words: Recursive Descent is inherently greedy (however, see <a href="rationale.html#exhaustive_rd">Exhaustive
-  backtracking and greedy RD</a>).</p>
+ backtracking and greedy RD</a>).<br>换句话说:递归下降本身就是贪心的(不 过,请看 <a href="rationale.html#exhaustive_rd">完全回溯和贪心RD</a>)。</p> <p><span class="special"></span><strong><a name="referencing_a_rule_at_construction" id="referencing_a_rule_at_construction"></a>Referencing
-  a rule at construction time</strong></p>
-<p><font color="#FF0000">Question:</font> The code below terminates with a segmentation
-  fault, but I'm (obviously) confused about what I'm doing wrong.</p>
+  a rule at construction time 在构造期引用规则</strong></p>
+<p><font color="#ff0000">Question:</font> The code below terminates with a segmentation + fault, but I'm (obviously) confused about what I'm doing wrong.<br><font color="#ff0000">问题:</font>以下代码导致了段错误,但我(显然)没弄明白自己错 在哪里。</p> <pre> rule<span class="special">&lt;</span>ScannerT<span class="special">,</span> clos<span class="special">::</span>context_t<span class="special">&gt;</span> id <span class="special">=</span> int_p<span class="special">[</span>id<span class="special">.</span>i <span class="special">=</span> arg1<span class="special">];</span></pre> <p>You have a rule <tt>id</tt> being constructed. Before it is constructed, you reference <tt>id.i</tt> in the RHS of the constructor. It's a chicken and egg thing. The closure member <tt>id.i</tt> is not yet constructed at that point.
-  Using assignment will solve the problem. Try this instead:</p>
+ Using assignment will solve the problem. Try this instead:<br>你有一个规 则 <tt>id</tt> 正被构造。在它构造完成之前,你在其构造函数的RHS中引用了 <tt>id.i</tt>。这是鸡和蛋的问题。闭包成员 <tt>id.i</tt> 在此时尚未构造。使用 赋值可以解决这个问题。试试这个:</p> <pre> rule<span class="special">&lt;</span>ScannerT<span class="special">,</span> clos<span class="special">::</span>context_t<span class="special">&gt;</span> id<span class="special">;</span> id <span class="special">=</span> int_p<span class="special">[</span>id<span class="special">.</span>i <span class="special">=</span> arg1<span class="special">];</span></pre> <p><span class="special"></span><strong><a name="storing_rules" id="storing_rules"></a>Storing
-  Rules </strong></p>
-<p><font color="#FF0000">Question:</font> Why can't I store rules in STL containers
+  Rules 保存规则 </strong></p>
+<p><font color="#ff0000">Question:</font> Why can't I store rules in STL containers for later use and why can't I pass and return rules to and from functions by
-  value? </p>
+ value?<br><font color="#ff0000">问题:</font>为什么我不能将规则保存在 STL容器中以备后用,还有,为什么我不能以传值的方式向函数传入或从函数返回规 则? </p> <p>EBNF is primarily declarative. Like in functional programming, It's a static recipe and there's no notion of do this then that. However, in Spirit, we managed to coax imperative C++ to take in declarative EBNF. Hah! Fun!... We did that
@@ -375,68 +358,89 @@
constructor) a different meaning and semantics. Doing so made the rule unlike any other C++ object. You can't copy it. You can't assign it. You can't place it in a container (vector, stack, etc).Heck, you can't even return it from a
-  function *by value*.</p>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"><img src="theme/alert.gif" width="16" height="16"> The + function *by value*.<br>EBNF是声明式的。类似于函数式编程,它是一些静态的 声明,且没有这样做的概念。但是,在Spirit中,我们必须设法让C++参与到声明式的 EBNF中。哈!有趣!... 我们通过伪装C++的赋值操作符以模仿EBNF的 <tt>::=</tt>,其它东西外(如 <tt>&gt;&gt;</tt>, <tt>|</tt>, <tt>&amp;</tt> +等等)除外。我们使用 rule 类来实现这一点,通过给予其赋值操作符(及复制构造函 数)一个不同的意义和语义。这样做使得 rule +与其它C++对象不一样。你不能复制它。你不能赋值它。你不能把它放入容器 (vector, stack,
+等等)中。哎呀,你甚至不能从一个函数返回它 *以传值的方式*。</p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><img src="theme/alert.gif" height="16" width="16"> The rule is a weird object, unlike any other C++ object. It does not have the proper copy and assignment semantics and cannot be stored and passed around
-      by value.</td>
+ by value.<br><img src="theme/alert.gif" height="16" width="16"> 规则 是一种奇怪的对象,与其它C++对象不一样。它没有正确的复制和赋值语义,也不能被 保存或以值方式传递。</td>
   </tr>
-</table>
+</tbody></table>
<p>However nice declarative EBNF is, the dynamic nature of C++ can be an advantage. We've seen this in action here and there. There are indeed some interesting applications of dynamic parsers using Spirit. Yet, we haven't fully utilized the power of dynamic parsing, unless(!), we have a rule that's not so alien to C++ (i.e. behaves as a good C++ object). With such a beast, we can write
-  parsers that's defined at run time, as opposed to at compile time.</p>
+  parsers that's defined at run time, as opposed to at compile time.<br>虽
+然声明式EBNF是好,但C++的动态特性也可以是一种优势。我们已经各处的动作中见过 这一咪。确有一些使用Spirit的动态分析器的有趣应用。然而,
+我们还没有充分利用动态分析的力量,除非(!)我们有一个对于C++不那么陌生的 rule
+(即其行为是一个好的C++对象)。有了这样一个东西,我们就可以写出在运行期而非编 译期定义的分析器了。</p> <p>Now that I started focusing on rules (hey, check out the hunky new rule features), it might be a good time to implement the rule-holder. It is basically just a rule, but with C++ object semantics. Yet it's not as simple. Without true garbage collection, the implementation will be a bit tricky. We can't simply use reference counting because a rule-holder (hey, anyone here has a better name?) *is-a* rule, and rules are typically recursive and thus cyclic. The problem is which
-  will own which.</p>
+  will own which.<br>现
+在,我开始关注于规则(嘿,找出hunky新规则特性),它可能是实现规则保存器的好时 机。基本上它只是一个规则,但具有C++对象的语义。然而事情并非 +这么简单。没有真正的垃圾回收机制,这个实现将会有些棘手。我们不能只是使用引 用计数,因为规则保存器(嘿,其它人有更好的名字吗?)*is-a*规则,
+而规则典型是递归的,这会导致循环。问题是谁将拥有谁。</p>
<p>Ok... this will do for now. You'll definitely see more of the rule-holder in
-  the coming days.</p>
-<p><strong><a name="parsing_ints_and_reals"></a>Parsing Ints and Reals</strong></p> -<p> <font color="#FF0000">Question:</font> I was trying to parse an int or float value with the <tt>longest_d</tt> directive and put some actors on the alternatives to visualize the results. When I parse &quot;123.456&quot;, the output reports:</p> + the coming days.<br>Ok... 现在将要开始实现它。你肯定在不久就会看到更多关 于规则保存器的东西。</p> +<p><strong><a name="parsing_ints_and_reals"></a>Parsing Ints and Reals 分析 整数和实数</strong></p> +<p> <font color="#ff0000">Question:</font> I was trying to parse an int or float value with the <tt>longest_d</tt> directive and put some actors on the alternatives to visualize the results. When I parse "123.456", the output reports:<br><font color="#ff0000">问题:</font>我尝试用 <tt>longest_d</tt> 指示符分析一个整数或浮点数,并在选择中置入一些动作以得到 结果。当我分析 "123.456" 时,输出:</p>
 <ol>
   <li>(int) has been matched: full match = false</li>
   <li> (double) has been matched: full match = true</li>
 </ol>
-<p>That is not what I expected. What am I missing? </p>
-<p> Actually, the problem is that both semantic actions of the int and real branch will be triggered because both branches will be tried. This doesn't buy us much. What actually wins in the end is what you expected. But there's no easy way to know which one wins. The problem stems from the ambiguity. </p> +<p>That is not what I expected. What am I missing?<br>这不是我想要的。我哪 里搞错了? </p>
+<p> Actually, the problem is that both semantic actions of the int and
+real branch will be triggered because both branches will be tried. This
+doesn't buy us much. What actually wins in the end is what you
+expected. But there's no easy way to know which one wins. The problem
+stems from the ambiguity.<br>实际上,问题是整数和实数分支的语义动作都被触发 了,因为两个分支均被尝试。这对我们没什么意义。最后哪个分支胜出才是你想要的。 不过却没有简单的方法来获知哪一个胜出。这个问题源自于歧义性。 </p>
 <blockquote>
- <p>Case1: Consider this input: &quot;2&quot;. Is it an int or a real? They are both (strictly following the grammar of a real). </p> - <p>Case2 : Now how about &quot;1.0&quot;? Is it an int or a real? They are both, albeit the int part gets a partial match: &quot;1&quot;. That is why you are getting a (partial) match for your <em>int</em> rule (full match = false). </p> + <p>Case1: Consider this input: "2". Is it an int or a real? They are both (strictly following the grammar of a real).<br>Case1: 考虑输入 "2"。它 是一个整数还是一个实数?两者都是(严格符合实数的语法)。 </p>
+  <p>Case2
+: Now how about "1.0"? Is it an int or a real? They are both, albeit
+the int part gets a partial match: "1". That is why you are getting a
+(partial) match for your <em>int</em> rule (full match = false).<br>Case2
+: 那么输入 "1.0" 又如何?它是一个整数还是一个实数?两者都是,虽然整数部分只 获得部分匹配:"1"。这就是为什么你从 <em>int</em> 规则获得一个(部分)匹配的原 因(full match = false)。 </p>
 </blockquote>
-<p> Instead of using the <tt>longest_d</tt> to parse ints and reals, what I suggest is to remove the ambiguity and use the plain short-circuiting alternatives. The first step is to use <tt><a href="numerics.html#strict_reals">strict_real_p</a> </tt>to make the first case unambiguous. Unlike
+<p>  Instead of using the <tt>longest_d</tt> to parse ints and reals,
+what I suggest is to remove the ambiguity and use the plain
+short-circuiting alternatives. The first step is to use <tt><a href="numerics.html#strict_reals">strict_real_p</a> </tt>to make the first case unambiguous. Unlike


<tt>real_p</tt>, <tt>strict_real_p</tt> requires a dot to be present for a number to be considered a successful match.

-Your grammar can be written unambiguously as:</p>
+Your grammar can be written unambiguously as:<br>不要使用 <tt>longest_d</tt> 来分析整数和实数,我的建议是,去掉歧义性,使用普通的短路 选择。第一步是使用 <tt><a href="numerics.html#strict_reals">strict_real_p</a> </tt>来令第一种情况没有 歧义。与
+
+
+ <tt>real_p</tt> 不同,<tt>strict_real_p</tt> 要求数字要有一个小数点才被认 为是成功的匹配。你的语法可以无歧义地写为:</p>
 <pre>    strict_real_p<span class="special"> | </span>int_p</pre>
-<p> Note that because ambiguity is resolved, attaching actions to both branches is safe. Only one will be triggered:</p> +<p> Note that because ambiguity is resolved, attaching actions to both branches is safe. Only one will be triggered:<br>注意,因为歧义性得到解 决,向两个分支附加动作是安全的了。只有一个会被触发:</p> <pre> strict_real_p<span class="special">[</span>R<span class="special">] | </span>int_p<span class="special">[</span>I<span class="special">]</span></pre>
 <blockquote>
-  <p> &quot;1.0&quot; ---&gt; triggers R<br>
-&quot;2&quot; ---&gt; triggers I</p>
+  <p> "1.0" ---&gt; triggers R<br>
+"2" ---&gt; triggers I</p>
 </blockquote>
-<p> Again, as a rule of thumb, it is always best to resolve as much ambiguity as possible. The best grammars are those which involve no backtracking at all: an LL(1) grammar. Backtracking and semantic actions do not mix well.</p>
+<p> Again, as a rule of thumb, it is always best to resolve as much
+ambiguity as possible. The best grammars are those which involve no
+backtracking at all: an LL(1) grammar. Backtracking and semantic
+actions do not mix well.<br>同样,作为一个经验法则,最好总是解决尽可能多的 歧义性。最好的语法是那些不需要回溯的语法:一个 LL(1) 语法。回溯和语义动作混 用不是太好。</p> <p><b><a name="output_operator" id="output_operator"></a>BOOST_SPIRIT_DEBUG and missing <tt>operator&lt;&lt;</tt></b></p> -<p><font color="#FF0000">Question:</font> My code compiles fine in release mode but when I try to define <tt>BOOST_SPIRIT_DEBUG</tt> the compiler complains about a missing <tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>.</p> +<p><font color="#ff0000">Question:</font> My code compiles fine in release mode but when I try to define <tt>BOOST_SPIRIT_DEBUG</tt> the compiler complains about a missing <tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>.<br><font color="#ff0000">问 题:</font>我们代码在发布模式下可正常编译,但当我尝试定义 <tt>BOOST_SPIRIT_DEBUG</tt> 时,编译器投诉缺少 <tt><span class="keyword">operator</span><span class="special">&lt;&lt;</span></tt>。 </p> <p>When <tt>BOOST_SPIRIT_DEBUG</tt> is defined debug output is generated for spirit parsers. To this end it is expected that each closure member has the
-  default output operator defined.</p>
+ default output operator defined.<br>当 <tt>BOOST_SPIRIT_DEBUG</tt> 被定义 时,将为spirit分析器生成调试输出。为此,要求每一个闭包成员都带有缺省的输出操 作符定义。</p>
 <p>You may provide the operator overload either in the namespace where the
class is declared (will be found through Argument Dependent Lookup) or make it visible where it is
-  used, that is <tt><span class="keyword">namespace</span> <span
-  class="identifier">boost</span><span class="special">::</span><span
-  class="identifier">spirit</span></tt>. Here's an example for <tt><span
-  class="identifier">std</span><span class="special">::</span><span
-  class="identifier">pair</span></tt>:</p>
+ used, that is <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt>. Here's an example for <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt>:<br>你可以在该类被定义的名字空间中提供这 个操作符(可通过ADL查找得到),或者在使用它的地方,即 <tt><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span></tt> 处令其 可见。以下是一个关于 <tt><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span></tt> 的例 子:</p>
 <pre><code>
<span class="preprocessor">#include</span> <span class="string">&lt;iosfwd&gt;</span> <span class="preprocessor">#include</span> <span class="string">&lt;utility&gt;</span>
@@ -460,47 +464,47 @@
     <span class="special">}</span>

 </code></pre>
-<p><b><a name="repository" id="repository"></a>Applications that used to be part of spirit</b></p> -<p><font color="#FF0000">Question:</font> Where can I find <i>&lt;insert great application&gt;</i>, that used to be part of the Spirit distribution?</p> +<p><b><a name="repository" id="repository"></a>Applications that used to be part of spirit 以前作为spirit一部分的应用程序</b></p> +<p><font color="#ff0000">Question:</font> Where can I find <i>&lt;insert great application&gt;</i>, that used to be part of the Spirit distribution?<br><font color="#ff0000">问题:</font>我可以在哪里找到 <i>&lt;insert great application&gt;</i>,被用作Spirit发布包的一部分的?</p>
 <p>Old versions of Spirit used to include applications built with it.
   In order to streamline the distribution they were moved to a separate
<a href="http://spirit.sourceforge.net/repository/applications/show_contents.php";>applications repository</a>.
   In that page you'll find links to full applications that use the Spirit
   parser framework. We encourage you to send in your own applications for
-  inclusion (see the page for instructions).</p>
- <p>You may also check out the <a href="http://spirit.sourceforge.net/repository/grammars/show_contents.php";>grammars' repository</a>.</p>
-<table width="80%" border="0" align="center">
-  <tr>
+ inclusion (see the page for instructions).<br>Spirit的旧版本通常会包含一 些用spirit来构建的应用程序。为了简化发布包,它们被移至了单独的 + <a href="http://spirit.sourceforge.net/repository/applications/show_contents.php";>应 用程序仓库</a>。在那里,你可以找到一些链接,链至一些使用了Spirit分析器框架的 完整的应用程序。我们鼓励你将你自己的应用程序也发至此处(请见指示页)。</p> + <p>You may also check out the <a href="http://spirit.sourceforge.net/repository/grammars/show_contents.php";>grammars' repository</a>.<br>你也可以检查一下 <a href="http://spirit.sourceforge.net/repository/grammars/show_contents.php";>语 法仓库</a>。</p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
     <td class="note_box">
- <img src="theme/note.gif" width="16" height="16"> You'll still find the + <img src="theme/note.gif" height="16" width="16"> You'll still find the
       example applications that complement (actually are part of) the
- documentation in the usual place: <code>libs/spirit/example</code>.<br> + documentation in the usual place: <code>libs/spirit/example</code>.<br><img src="theme/note.gif" height="16" width="16"> 你仍然可以在老地方 <code>libs/spirit/example</code> 找到作为文档 补充(其实是文档的一部分)的例子应用程序。<br>
       <br>
- <img src="theme/alert.gif" width="16" height="16"> The applications and + <img src="theme/alert.gif" height="16" width="16"> The applications and grammars listed in the repositories are works of the respective authors.
       It is the author's responsibility to provide support and maintenance.
-      Should you have any questions, please send the author an email.
+ Should you have any questions, please send the author an email.<br><img src="theme/alert.gif" height="16" width="16"> 在仓库中列出的 应用程序和语法是各个作者的作品。提供支持和维护是各位作者的责任。如果你有任何 问题,请给作者发送email。
     </td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="techniques.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="rationale.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
-<span class="copyright">Copyright &copy; 2002-2003 Hartmut Kaiser </span><br> -<span class="copyright">Copyright &copy; 2006-2007 Tobias Schwinger </span><br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
+<span class="copyright">Copyright © 2002-2003 Hartmut Kaiser </span><br>
+<span class="copyright">Copyright © 2006-2007 Tobias Schwinger </span><br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/file_iterator.html Tue Mar 31 01:07:16 2009 +++ /trunk/libs/spirit/classic/doc/file_iterator.html Mon Oct 12 20:27:43 2009
@@ -1,97 +1,76 @@
-<html>
-<head>
-<title>File Iterator</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>File Iterator</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
     <td width="85%">
- <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>File Iterator</b></font> + <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>File Iterator 文件迭代器</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="multi_pass.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="position_iterator.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>Since Spirit is a back-tracking parser, it requires at least a forward iterator. In particular, an input iterator is not sufficient. Many times it is convenient to read the input to a parser from a file, but the STL file iterators are input iterators. To get around this limitation, Spirit has a utility class <tt>file_iterator</tt>,
-  which is a read-only random-access iterator for files.</p>
+ which is a read-only random-access iterator for files.<br>由于Spirit是一 个后向跟踪分析器,它要求至少一个前向迭代器。特别是,输入迭代器是不够的。很多 时候从一个文件读入数据至分析器是很方便的,但是STL的文件迭代器是输入迭代器。 为了避开这个限制,Spirit有一个工具类 <tt>file_iterator</tt>,它是文件的只读 随机访问迭代器。</p> <p>To use the Spirit file iterator, simply create a file iterator with the path - to the file you wish to parse, and then create an EOF iterator for the file:</p> -<pre><span class=identifier> </span><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>spirit</span><span class=special>/</span><span class=identifier>iterator</span><span class=special>/</span><span class=identifier>file_iterator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt; </span><span class=comment>// the header file</span></pre> -<pre> <span class=identifier>file_iterator</span><span class=special>&lt;&gt; </span><span class=identifier>first</span><span class=special>(</span><span class=string>&quot;input.dat&quot;</span><span class=special>);
-
- </span><span class=keyword>if </span><span class=special>(!</span><span class=identifier>first</span><span class=special>)
-    {
- </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>&quot;Unable to open file!\n&quot;</span><span class=special>;
-
-       </span><span class=comment>// Clean up, throw an exception, whatever
- </span><span class=keyword>return </span><span class=special>-</span><span class=number>1</span><span class=special>;
-    }
-
- </span><span class=identifier>file_iterator</span><span class=special>&lt;&gt; </span><span class=identifier>last </span><span class=special>= </span><span class=identifier>first</span><span class=special>.</span><span class=identifier>make_end</span><span class=special>();</span></pre> + to the file you wish to parse, and then create an EOF iterator for the file:<br>要使用Spirit的文件迭代器,只需用你想要分析的文件的路径名去创建一个 文件迭代器即可,然后为该文件创建一个EOF迭代器:</p> +<pre><span class="identifier"> </span><span class="preprocessor">#include </span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">file_iterator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; </span><span class="comment">// the header file 头文件</span></pre> +<pre> <span class="identifier">file_iterator</span><span class="special">&lt;&gt; </span><span class="identifier">first</span><span class="special">(</span><span class="string">"input.dat"</span><span class="special">);<br><br> </span><span class="keyword">if </span><span class="special">(!</span><span class="identifier">first</span><span class="special">)<br> {<br> </span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout </span><span class="special">&lt;&lt; </span><span class="string">"Unable to open file!\n"</span><span class="special">;<br><br> </span><span class="comment">// Clean up, throw an exception, whatever 清除,抛出一个异常,或其它<br> </span><span class="keyword">return </span><span class="special">-</span><span class="number">1</span><span class="special">;<br> }<br><br> </span><span class="identifier">file_iterator</span><span class="special">&lt;&gt; </span><span class="identifier">last </span><span class="special">= </span><span class="identifier">first</span><span class="special">.</span><span class="identifier">make_end</span><span class="special">();</span></pre> <p>You now have a pair of iterators to use with Spirit . If your parser is fully parametrized (no hard-coded <tt>&lt;char const *&gt;</tt>), it is a simple matter
-  of redefining the iterator type to <tt>file_iterator</tt>:<br>
+ of redefining the iterator type to <tt>file_iterator</tt>:<br>现在你有了 一对迭代器用于Spirit。如果你的分析器是完全参数化的(没有硬编码的 <tt>&lt;char const *&gt;</tt>),那么重新定义迭代器类型为 <tt>file_iterator</tt> 只是一件很简单的事情:<br>
 </p>
-<pre> <span class=keyword>typedef char </span><span class="identifier">char_t</span><span class=special>; - </span><span class=keyword>typedef </span><span class=identifier>file_iterator </span><span class=special>&lt;</span><span class=keyword>char</span><span class=identifier>_t</span><span class=special>&gt; </span><span class=identifier>iterator_t</span><span class=special>; - </span><span class=keyword>typedef </span><span class=identifier>scanner</span><span class=special>&lt;</span><span class=identifier>iterator_t</span><span class=special>&gt; </span><span class=identifier>scanner_t</span><span class=special>; - </span><span class=keyword>typedef </span><span class=identifier>rule </span><span class=special>&lt;</span><span class=identifier>scanner_t</span><span class=special>&gt; </span><span class=identifier>rule_t</span><span class=special>;
-
- </span><span class=identifier>rule_t my_rule</span><span class=special>;
-
-    </span><span class=comment>// Define your rule
-
- </span><span class=identifier>parse_info</span><span class=special>&lt;</span><span class=identifier>iterator_t</span><span class=special>&gt; </span><span class=identifier>info </span><span class=special>= </span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>my_rule</span><span class=special>);</span></pre> +<pre> <span class="keyword">typedef char </span><span class="identifier">char_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">file_iterator </span><span class="special">&lt;</span><span class="keyword">char</span><span class="identifier">_t</span><span class="special">&gt; </span><span class="identifier">iterator_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">scanner</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">&gt; </span><span class="identifier">scanner_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">rule </span><span class="special">&lt;</span><span class="identifier">scanner_t</span><span class="special">&gt; </span><span class="identifier">rule_t</span><span class="special">;<br><br> </span><span class="identifier">rule_t my_rule</span><span class="special">;<br><br> </span><span class="comment">// Define your rule 定义你的规则<br><br> </span><span class="identifier">parse_info</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">&gt; </span><span class="identifier">info </span><span class="special">= </span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">, </span><span class="identifier">my_rule</span><span class="special">);</span></pre> <p>Of course, you don't have to deal with the <a href="faq.html#scanner_business">scanner-business</a> at all if you use grammars rather than rules as arguments to the parse functions. - You simply pass the iterator pairs and the grammar as is:<span class=special><br> + You simply pass the iterator pairs and the grammar as is:<br>当然,你根本 不必处理 <a href="faq.html#scanner_business">扫描器事务</a>,如果你用语法而 不是规则作为 parse 函数的参数。你只要传入迭代器对和语法如下:<span class="special"><br>
   </span></p>
-<pre> <span class=identifier>my_grammar </span><span class=identifier>g</span><span class=special>; - </span><span class=identifier>parse_info</span><span class=special>&lt;</span><span class=identifier>iterator_t</span><span class=special>&gt; </span><span class=identifier>info </span><span class=special>= </span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>g</span><span class=special>);</span></pre>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"><img src="theme/bulb.gif" width="13" height="18"><b>
-      Generic iterator</b><br>
+<pre> <span class="identifier">my_grammar </span><span class="identifier">g</span><span class="special">;<br> </span><span class="identifier">parse_info</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">&gt; </span><span class="identifier">info </span><span class="special">= </span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">, </span><span class="identifier">g</span><span class="special">);</span></pre>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><img src="theme/bulb.gif" height="18" width="13"><b>
+      Generic iterator 泛型迭代器</b><br>
       <br>
The Spirit file iterator can be parameterized with any type that is default constructible and assignable. It transparently supports large files (greater than 2GB) on systems that provide an appropriate interface. The file iterator can be useful outside of Spirit as well. For instance, the Boost.Tokenizer - package requires a bidirectional iterator, which is provided by file_iterator.</td> + package requires a bidirectional iterator, which is provided by file_iterator.<br> + Spirit文件迭代器可以按任何可缺省构造及可赋值的类型参数化。在提供了适 当接口的系统上,它透明地支持大文件(大于2GB)。该文件迭代器也可以在Spirit之外 使用。例如,Boost.Tokenizer
+      包要求一个双向迭代器,就是由 file_iterator 提供的。</td>
   </tr>
-</table>
-<p><img src="theme/lens.gif" width="15" height="16"> See <a href="../example/fundamental/file_parser.cpp">file_parser.cpp</a> for a compilable example. This is part of the Spirit distribution.</p>
+</tbody></table>
+<p><img src="theme/lens.gif" height="16" width="15"> See <a href="../example/fundamental/file_parser.cpp">file_parser.cpp</a> for a compilable example. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 可编译的例子请见 <a href="../example/fundamental/file_parser.cpp">file_parser.cpp</a>。这是 Spirit发布包的一部分。</p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="multi_pass.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="position_iterator.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2002 Jeff Westfahl</p>
+<p class="copyright">Copyright © 2002 Jeff Westfahl</p>
<p class="copyright"><font size="2"> Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)
  </font> </p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/includes.html        Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/includes.html        Mon Oct 12 20:27:43 2009
@@ -1,56 +1,53 @@
-<html>
-<head>
-<title>Includes</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Includes</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Includes</b></font> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Includes 头文件</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="quickref.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="portability.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
-<h2>Modules</h2>
-<p>Spirit is designed to be header only. Generally, there are no libraries to build
+</tbody></table>
+<h2>Modules 模块</h2><p>Spirit is designed to be header only. Generally, there are no libraries to build and link against. Certain features, however, require additional libraries; in particular the <a href="regular_expression_parser.html">regular expression parser</a> requires <a href="http://www.boost.org/libs/regex/index.html";>Boost.Regex</a> and <a href="grammar.html#multithreading">multithreading support</a> -requires <a href="http://www.boost.org/libs/thread/doc/index.html";>Boost.Threads.</a></p>
-<p>Using Spirit is as easy as including the main header file:</p>
+requires <a href="http://www.boost.org/libs/thread/doc/index.html";>Boost.Threads.</a><br>Spirit被 设计为只带头文件的。通常,没有库需要构建和链接。但是,某些特定的特性需要其它 的库;如 <a href="regular_expression_parser.html">正则表达式分析器</a> 需要 +<a href="http://www.boost.org/libs/regex/index.html";>Boost.Regex</a>,而 <a href="grammar.html#multithreading">多线程支持</a> +则需要 <a href="http://www.boost.org/libs/thread/doc/index.html";>Boost.Threads。 </a></p> +<p>Using Spirit is as easy as including the main header file:<br>使用 Spirit很容易,只要包含以下主头文件即可:</p> <pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">.</span>hpp<span class="special">&gt;</span></pre> <p>Doing so will include all the header files. This might not be desirable. A low cholesterol alternative is to include only the module that you need. Each of the modules has its own header file. The master spirit header file actually includes all the module files. To avoid unnecessary inclusion of features that - you do not need, it is better to include only the modules that you need.</p> -<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">.</span>hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">.</span>hpp<span class="special">&gt; - <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>core<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> + you do not need, it is better to include only the modules that you need.<br>这样做将包含所有头文件。这可能不是你想要的。较为瘦身一点的选择 是,只包含你所需的头文件。每个模块都有它自己的头文件。spirit的主头文件其实就 是包含所有的模块文件。为了避免包含你不需要的特性的头文件,最好只包含你所要的 模块。</p> +<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">.</span>hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">.</span>hpp<span class="special">&gt;<br> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>core<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> </span><span class="special"></span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>debug<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> </span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>dynamic<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>error_handling<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"> - <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>iterator<span class="special">.</span>hpp<span class="special">&gt; - <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>meta<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> + <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>iterator<span class="special">.</span>hpp<span class="special">&gt;<br> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>meta<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"> </span><span class="special"></span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>symbols<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>tree<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"> <span class="preprocessor">#include</span> &lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>utility<span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span></pre>
-<h2>Sub-Modules</h2>
+<h2>Sub-Modules 子模块</h2>
<p> For even finer control over header file inclusion, you can include only the - specific files that you need. Each module is in its own sub-directory:</p>
-<h3>actor</h3>
+ specific files that you need. Each module is in its own sub-directory:<br>为了更好地控制对头文件的包含,你可以只包含所需的专用文件。 每个模块都位于各自的子目录中:</p>
+<h3>actor 动作器</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">assign_actor</span><span class="special">.</span>hpp<span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">assign_key</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">clear_actor</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">decrement_actor</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span>
@@ -58,57 +55,43 @@
<span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">push_back_actor</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">push_front_actor</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>actor<span class="special">/</span><span class="identifier">swap_actor</span><span class="special">.</span>hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span></pre>
-<h3>attribute</h3>
+<h3>attribute 属性</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">/</span><span class="identifier">closure</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">/</span>closure_context.hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>attribute<span class="special">/</span>parametric.hpp<span class="special">&gt;</span></pre>
-<h3>debug</h3>
-<p><img src="theme/alert.gif" width="16" height="16"> The debug module should
+<h3>debug 调试</h3>
+<p><img src="theme/alert.gif" height="16" width="16"> The debug module should not be directly included. See <a href="debugging.html">Debugging</a> for more
-  info on how to use Spirit's debugger. </p>
-<h3>dynamic</h3>
+ info on how to use Spirit's debugger.<br><img src="theme/alert.gif" height="16" width="16"> 调试模块不应直接包含。有关如何使用Spirit的调试器的更 多信息,请见 <a href="debugging.html">Debugging</a>。 </p>
+<h3>dynamic 动态</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>dynamic<span class="special">/</span><span class="identifier">for</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>dynamic<span class="special">/</span>if.hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> - <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>lazy.hpp<span class="special">&gt; <br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>rule_alias.hpp<span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>select.hpp<span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>stored_rule.hpp<span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>switch.hpp<span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>while.hpp<span class="special">&gt; </span></pre>
-<h3>error_handling</h3>
+ <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>lazy.hpp<span class="special">&gt; <br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>rule_alias.hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>select.hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>stored_rule.hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>switch.hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">dynamic</span><span class="special">/</span>while.hpp<span class="special">&gt; </span></pre>
+<h3>error_handling 错误处理</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>error_handling<span class="special">/</span><span class="identifier">exceptions</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></pre>
-<h3>iterator</h3>
+<h3>iterator 迭代器</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>iterator<span class="special">/</span><span class="identifier">file_iterator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span>fixed_size_queue.hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span>multi_pass.hpp<span class="special">&gt; <br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span>position_iterator.hpp<span class="special">&gt;</span></pre>
-<h3>meta</h3>
+<h3>meta 元</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span>meta<span class="special">/</span><span class="identifier">as_parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">meta</span><span class="special">/</span>fundamental.hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">meta</span><span class="special">/</span>parser_traits.hpp<span class="special">&gt; <br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">meta</span><span class="special">/</span>refactoring.hpp<span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">meta</span><span class="special">/</span>traverse.hpp<span class="special">&gt;</span></pre>
-<h3>tree</h3>
+<h3>tree 树</h3>
<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">tree</span><span class="special">/</span><span class="identifier">ast</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">tree</span><span class="special">/</span>parse_tree.hpp<span class="special">&gt;</span><span class="special"></span><span class="special"></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">tree</span><span class="special">/</span>parse_tree_utils.hpp<span class="special">&gt;</span><span class="special"><br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">tree</span><span class="special">/</span>tree_to_xml.hpp<span class="special">&gt;</span></pre>
-<h3>utility</h3>
-<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">chset</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; <br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">chset_operators</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">distinct</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">escape_char</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">flush_multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">functor_parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">lists</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">loops</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">regex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; - </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">scoped_lock</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;
-</span></pre>
+<h3>utility 工具</h3>
+<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">chset</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt; <br></span> <span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">chset_operators</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">confix</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">distinct</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">escape_char</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">flush_multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">functor_parser</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">lists</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">loops</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">regex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br> </span><span class="preprocessor">#include</span> <span class="special">&lt;</span>boost<span class="special">/</span>spirit<span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">scoped_lock</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;<br></span></pre>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="quickref.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="portability.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/multi_pass.html      Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/multi_pass.html      Mon Oct 12 20:27:43 2009
@@ -1,16 +1,17 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>The multi_pass</title>
-
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>The multi_pass</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
   <tbody><tr>
     <td width="10">
     <br>
 </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>The + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>The
       multi_pass</b></font> </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
 </tbody></table>
 <br>
@@ -28,16 +29,19 @@
cannot be used. Therefore, the standard library classes istreambuf_iterator and istream_iterator, that fall under the category of input iterators, cannot be used. Another input iterator that is of interest is one that wraps a lexer,
-  such as LEX.</p>
-<table width="80%" border="0" align="center">
+  such as LEX.<br>Spirit
+中的回溯要求使用以下迭代器类型:前向迭代器、双向迭代器或随机访问迭代器。因 为要回溯,所以输入迭代器不能使用。因此,标准库类 +istreambuf_iterator 和 istream_iterator 均属于输入迭代器类别,都不能使用。 另一个感兴趣的输入迭代器是
+lexer 的封装,如 LEX.</p>
+<table align="center" border="0" width="80%">
   <tbody><tr>
- <td class="note_box"> <img src="theme/note.gif" width="16" height="16"> <b>Input
-      Iterators</b> <br>
+ <td class="note_box"> <img src="theme/note.gif" height="16" width="16"> <b>Input
+      Iterators</b> 输入迭代器 <br>
       <br>
In general, Spirit is a backtracking parser. This is not an absolute requirement though. In the future, we shall see more deterministic parsers that require no more than 1 character (token) of lookahead. Such parsers allow us to
-      use input iterators such as the istream_iterator as is. </td>
+ use input iterators such as the istream_iterator as is.<br>通 常,Spirit是一个回溯分析器。但这不是绝对的要求。未来我们将会看到更为确定的分 析器,要求前向环视不超过1个字符(记号)。这样的分析器允许我们使用输入迭代 器,如 istream_iterator 等等。 </td>
   </tr>
 </tbody></table>
<p> Unfortunately, with an input iterator, there is no way to save an iterator
@@ -45,48 +49,58 @@
One solution to this problem is to simply load all the data to be parsed into a container, such as a vector or deque, and then pass the begin and end of the container to Spirit. This method can be too memory intensive for certain applications,
-  which is why the multi_pass iterator was created.</p>
+  which is why the multi_pass iterator was created.<br>不
+幸的是,使用输入迭代器没有办法保存迭代器的位置,因此输入迭代器不能用于 Spirit中的回溯。这个问题的一个解决办法是,将要分析的所有数据导入到一
+个容器中,如 vector 或 deque,然后将该容器的 begin 和 end 传给
+Spirit。这个方法对于某个应用可能要耗费大量内存,这正是为什么要创建 multi_pass 迭代器的原因。</p> <p> The multi_pass iterator will convert any input iterator into a forward iterator suitable for use with Spirit. multi_pass will buffer data when needed and will
-  discard the buffer when only one copy of the iterator exists.</p>
+ discard the buffer when only one copy of the iterator exists.<br>multi_pass 迭代器可以将任意输入迭代器转换为适合Spirit使用的前向迭 代器。multi_pass 会在需要时缓冲数据,也会在只有一份迭代器拷贝时略过缓冲。 </p> <p> A grammar must be designed with care if the multi_pass iterator is used. Any rule that may need to backtrack, such as one that contains an alternative, will cause data to be buffered. The rules that are optimal to use are sequence and repetition. Sequences of the form <tt>a &gt;&gt; b</tt> will not buffer data at all. Any rule that repeats, such as kleene_star (<tt>*a</tt>) or positive such as (<tt>+a</tt>), will only buffer the data for the current
-  repetition.</p>
+ repetition.<br>如果要使用 multi_pass 迭代器,语法就必须小心地设计。任何规 则都可能需要回溯,例如一个含有选择的规则,这将导致数据被缓存。这些规则最好使 用序列和重复。形如 <tt>a &gt;&gt; b</tt>
+  的序列根本不会缓存数据。任何带有重复的规则,如 kleene_star (<tt>*a</tt>)
+  或加号如 (<tt>+a</tt>),则只缓存当前重复的数据。</p>
<p> In typical grammars, ambiguity and therefore lookahead is often localized. In fact, many well designed languages are fully deterministic and require no lookahead at all. Peeking at the first character from the input will immediately determine the alternative branch to take. Yet, even with highly ambiguous grammars, alternatives are often of the form <tt>*(a | b | c | d)</tt>. The input iterator moves on and is never stuck at the beginning. Let's look at a Pascal snippet
-  for example:</p>
+ for example:<br>在典型的语法中,模糊性以及所引起的前向环视通常是局部性 的。事实上,许多精心设计的语言是完全确定性的,根本不需要前向环视。从读进输入 的第一个字符开始,并立即决定选择哪个分支。然而,即使是非常模糊的语法,选择通 常也是 <tt>*(a | b | c | d)</tt> 这样的形式。输入迭代器向前移动,永远不会停 留在开始处。我们看一个Pascal片断的例子:</p> <pre> <code><span class="identifier">program </span><span class="special">=<br> </span><span class="identifier"> programHeading </span><span class="special">&gt;&gt; </span><span class="identifier">block </span><span class="special">&gt;&gt; </span><span class="literal">'.'<br> </span><span class="special"> ;<br><br> </span><span class="identifier">block </span><span class="special">=<br> *( </span><span class="identifier">labelDeclarationPart<br> </span><span class="special">| </span><span class="identifier">constantDefinitionPart<br> </span><span class="special">| </span><span class="identifier">typeDefinitionPart<br> </span><span class="special"> | </span><span class="identifier">variableDeclarationPart<br> </span><span class="special">| </span><span class="identifier"> procedureAndFunctionDeclarationPart<br> </span><span class="special"> )<br> &gt;&gt; </span><span class="identifier">statementPart<br> </span><span class="special">;<br></span></code></pre> <p> Notice the alternatives inside the Kleene star in the rule block . The rule gobbles the input in a linear manner and throws away the past history with each iteration. As this is fully deterministic LL(1) grammar, each failed alternative only has to peek 1 character (token). The alternative that consumes more than 1 character (token) is definitely a winner. After which, the Kleene star moves
-  on to the next.</p>
+  on to the next.<br>留
+意规则块中在 Kleene 星内部的多项选择。该规则以线性方式吞进输入,并丢掉每次 迭代的历史。因为这是完全确定性的 LL(1) +语法,每个失败的选择都只需检查1个字符(记号)。消耗1个以上字符(记号)的选择项 肯定是胜者。之后,Kleene 星前移至下一个。</p>
 <p>Be mindful if you use the free parse functions.
-  All of these make a copy of the iterator passed to them.<br>
+ All of these make a copy of the iterator passed to them.<br>紧记,如果你 使用自由的 parse 函数。所有这些会对传给它们的迭代器复制一份拷贝。<br>
 </p>
-<p>Now, after the lecture on the features to be careful with when using multi_pass,
-you may think that multi_pass is way too restrictive to use. &nbsp;That's
-not the case. &nbsp;If your grammar is deterministic, you can make use of flush_multi_pass in your grammar to ensure that data is not buffered when unnecessary.<br>
+<p>Now, after the lecture on the features to be careful with when using
+multi_pass,
+you may think that multi_pass is way too restrictive to use.
+&nbsp;That's
+not the case. &nbsp;If your grammar is deterministic, you can make use
+of flush_multi_pass in your grammar to ensure that data is not buffered
+when unnecessary.<br>现在,在介绍了使用
+multi_pass 时应注意的特性之后,你可能认为 multi_pass 过多限制难以使用。其实 不然。如果你的语法是确定性的,你就可以在你的语法中使用 flush_multi_pass 来确 保数据在不需要的时候不会被缓冲。<br>
 </p>

<p> Again, following up the example we started to use in the section on the scanner . Here's an example using the multi_pass: This time around we are extracting
-  our input from the input stream using an istreambuf_iterator.</p>
-<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> -<code><span class="preprocessor"> #include </span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="comment">
-
- </span><span class="keyword">using namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">; - </span><span class="keyword">using namespace</span> <span class="identifier">std</span><span class="special">;</span>
-
- <span class="identifier">ifstream in</span><span class="special">(</span><span class="string">"input_file.txt"</span><span class="special">); </span><span class="comment">// we get our input from this file<br><br> </span><span class="keyword">typedef char </span><span class="identifier">char_t</span><span class="special">;</span> + our input from the input stream using an istreambuf_iterator.<br>同样,跟 着我们在扫描器一章中的例子。以下是一个使用 multi_pass 的例子:这次我们使用一 个 istreambuf_iterator 从输入流中取出我们的输入。</p> +<pre> <span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">core</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span> <br><code><span class="preprocessor"> #include </span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="comment">
+
+ </span><span class="keyword">using namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;<br> </span><span class="keyword">using namespace</span> <span class="identifier">std</span><span class="special">;</span>
+
+ <span class="identifier">ifstream in</span><span class="special">(</span><span class="string">"input_file.txt"</span><span class="special">); </span><span class="comment">// we get our input from this file 我们从这个文件中输入<br><br> </span><span class="keyword">typedef char </span><span class="identifier">char_t</span><span class="special">;</span> <span class="keyword">typedef </span><span class="identifier">multi_pass</span><span class="special">&lt;</span><span class="identifier">istreambuf_iterator</span><span class="special">&lt;</span><span class="identifier">char_t</span><span class="special">&gt; &gt; </span><span class="identifier">iterator_t</span><span class="special">;</span>

<span class="keyword">typedef</span> <span class="identifier">skip_parser_iteration_policy</span><span class="special">&lt;</span><span class="identifier">space_parser</span><span class="special">&gt;</span> <span class="identifier">iter_policy_t</span><span class="special">;</span>
@@ -102,48 +116,51 @@

scanner_t <span class="identifier">scan</span><span class="special">(</span> first<span class="special">,</span> make_multi_pass(std::istreambuf_iterator<span class="special">&lt;</span><span class="identifier">char_t</span><span class="special">&gt;()),</span> - <span class="identifier">policies</span><span class="special">)</span>; -<span class="special"><br> </span><span class="identifier">rule_t n_list </span><span class="special">= </span><span class="identifier">real_p </span><span class="special">&gt;&gt; *(</span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">real_p</span><span class="special">);<br> </span><span class="identifier">match</span><span class="special">&lt;&gt;</span><span class="identifier"> m </span><span class="special">= </span><span class="identifier">n_list</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">scan</span><span class="special">);<br></span></code></pre> + <span class="identifier">policies</span><span class="special">)</span>;<br><span class="special"><br> </span><span class="identifier">rule_t n_list </span><span class="special">= </span><span class="identifier">real_p </span><span class="special">&gt;&gt; *(</span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">real_p</span><span class="special">);<br> </span><span class="identifier">match</span><span class="special">&lt;&gt;</span><span class="identifier"> m </span><span class="special">= </span><span class="identifier">n_list</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">scan</span><span class="special">);<br></span></code></pre>
 <a name="flush_multi_pass"></a>
 <h2>flush_multi_pass</h2>
<p> There is a predefined pseudo-parser called flush_multi_pass. When this parser is used with multi_pass, it will call multi_pass::clear_queue(). This will cause any buffered data to be erased. This also will invalidate all other copies of multi_pass and they should not be used. If they are, an boost::illegal_backtracking
-  exception will be thrown.</p>
+ exception will be thrown.<br>有一个预定义的伪分析器,名为 flush_multi_pass。当你将这个分析器用于 multi_pass 时,它将调用 multi_pass::clear_queue()。这将导致所有缓冲数据被删除。同时令 + multi_pass 的所有其它拷贝失效并不能再使用。如果它们再被使用,将抛出一个 boost::illegal_backtracking
+  异常。</p>
 <a name="multi_pass_policies"></a>
 <h2>multi_pass Policies</h2>
-<p> multi_pass is a templated policy driven class. The description of multi_pass +<p>multi_pass is a templated policy driven class. The description of multi_pass above is how it was originally implemented (before it used policies), and is the default configuration now. But, multi_pass is capable of much more. Because of the open-ended nature of policies, you can write your own policy to make
-  multi_pass behave in a way that we never before imagined.</p>
-<p> The multi_pass class has five template parameters:</p>
+ multi_pass behave in a way that we never before imagined.<br>multi_pass 是一个模板化的策略驱动类。以上对于 multi_pass + 的说明是它原先是如何被实现的(在使用策略之前),也是现在的缺省配置。但 是,multi_pass 具有更多的能力。因为策略的 open-ended 特点,你可以编写你自己 的策略来令
+  multi_pass 以我们从未想过的方式来工作。</p>
+<p> The multi_pass class has five template parameters:<br>multi_pass 类有五 个模板参数:</p>
 <ul>
<li>InputT - The type multi_pass uses to acquire it's input. This is typically
-    an input iterator, or functor.</li>
+ an input iterator, or functor.<br>InputT - multi_pass 用于获取输入的类 型。典型是一个输入迭代器或仿函数。</li> <li>InputPolicy - A class that defines how multi_pass acquires it's input. The
-    InputPolicy is parameterized by InputT.</li>
+ InputPolicy is parameterized by InputT.<br>InputPolicy - 定义 multi_pass 如何获取其输入的类。InputPolicy 按 InputT 参数化。</li> <li>OwnershipPolicy - This policy determines how multi_pass deals with it's
-    shared components.</li>
+ shared components.<br>OwnershipPolicy - 这个策略决定 multi_pass 如何处 理它的共享组件。</li> <li>CheckingPolicy - This policy determines how checking for invalid iterators
-    is done.</li>
+    is done.<br>CheckingPolicy - 这个策略决定如何检查无效迭代器。</li>
<li>StoragePolicy - The buffering scheme used by multi_pass is determined and
-    managed by the StoragePolicy.</li>
+ managed by the StoragePolicy.<br>StoragePolicy - multi_pass 所使用的缓 冲机制由 StoragePolicy 确定及管理。</li>
 </ul>
 <a name="predefined_policies"></a>
-<h2>Predefined policies</h2>
-<p> All predefined multi_pass policies are in the namespace boost::spirit::multi_pass_policies.</p>
+<h2>Predefined policies 预定义策略</h2>
+<p> All predefined multi_pass policies are in the namespace boost::spirit::multi_pass_policies.<br>所有预定义的 multi_pass 策略位于名字 空间 boost::spirit::multi_pass_policies。</p>
 <a name="predefined_inputpolicy_classes"></a>
-<h3>Predefined InputPolicy classes</h3>
+<h3>Predefined InputPolicy classes 预定义的InputPolicy类</h3>
 <a name="input_iterator"></a>
 <h4>input_iterator</h4>
-<p> This policy directs multi_pass to read from an input iterator of type InputT.</p> +<p> This policy directs multi_pass to read from an input iterator of type InputT.<br>这个策略指示 multi_pass 从一个类型为 InputT 的输入迭代器读入。 </p>
 <a name="lex_input"></a>
 <h4>lex_input</h4>
<p> This policy obtains it's input by calling yylex(), which would typically be provided by a scanner generated by LEX. If you use this policy your code must
-  link against a LEX generated scanner.</p>
+ link against a LEX generated scanner.<br>这个策略通过调用 yylex() 获得其 输入,该函数通常是由LEX所生成的扫描器提供的。如果你使用了该策略,则你的代码 必须与某个LEX生成的扫描器相链接。</p>
 <a name="functor_input"></a>
 <h4>functor_input</h4>
<p> This input policy obtains it's data by calling a functor of type InputT. The
@@ -151,24 +168,31 @@
which should be the type returned from operator(). Also, since an input policy needs a way to determine when the end of input has been reached, the functor must contain a static variable named eof which is comparable to a variable of
-  result_type.</p>
+  result_type.<br>这
+种输入策略通过调用类型为 InputT 仿函数获得其数据。该仿函数必须满足某些要 求。它必须有一个名为 result_type 的
+typedef,是从
+operator()&nbsp;返回的类型。此外,由于输入策略需要一种方法来确定输入何时到 达结尾,所以该仿函数必须包含一个名为 eof
+的静态变量,它应该可以与 result_type 变量相比较。</p>
 <a name="predefined_ownershippolicy_classes"></a>
-<h3>Predefined OwnershipPolicy classes</h3>
+<h3>Predefined OwnershipPolicy classes 预定义的所有权策略类</h3>
 <a name="ref_counted"></a>
 <h4>ref_counted</h4>
<p> This class uses a reference counting scheme. multi_pass will delete it's shared
-  components when the count reaches zero.</p>
+ components when the count reaches zero.<br>这个类使用一个引用计数机制。 multi_pass 将在该计数为零时删除其共享组件。</p>
 <a name="first_owner"></a>
 <h4>first_owner</h4>
<p> When this policy is used, the first multi_pass created will be the one that deletes the shared data. Each copy will not take ownership of the shared data. This works well for spirit, since no dynamic allocation of iterators is done. - All copies are made on the stack, so the original iterator has the longest lifespan.</p> + All copies are made on the stack, so the original iterator has the longest lifespan.<br>使
+用这个策略时,第一个创建的 multi_pass&nbsp;将是负责删除共享数据的
+multi_pass。每个副本不会获取共享数据的所有权。这种方法在 spirit
+行之有效,因为没有迭代器的动态分配要做。所有副本都是基于堆栈,所以原来的迭 代器具有最长的寿命。</p>
 <a name="predefined_checkingpolicy_classes"></a>
-<h3>Predefined CheckingPolicy classes</h3>
+<h3>Predefined CheckingPolicy classes 预定义的检查策略类</h3>
 <a name="no_check"></a>
 <h4>no_check</h4>
-<p> This policy does no checking at all.</p>
+<p> This policy does no checking at all.<br>该策略不进行检查。</p>
 <a name="buf_id_check"></a>
 <h4>buf_id_check</h4>
<p> buf_id_check keeps around a buffer id, or a buffer age. Every time clear_queue()
@@ -178,19 +202,21 @@
of the iterator matches the shared buffer id. This policy is most effective when used together with the std_deque StoragePolicy. It should not be used with the fixed_size_queue StoragePolicy, because it will not detect iterator dereferences
-  that are out of range.</p>
+ that are out of range.<br>buf_id_check 保持一个缓冲区 id,或一个缓冲区寿 命。每次对一个 multi_pass 迭代器调用 clear_queue(),有可能所有其它的迭代器都 变为无效。在调用 clear_queue() 时,buf_id_check 递增该缓冲区
+  id。当一个迭代器被提领时,该策略检查该迭代器的缓冲区 id
+ 是否与共享缓冲区 id 相匹配。在与 std_deque 存储策略一起使用时,该策略是最 高效的。但它不能与 fixed_size_queue 存储策略共用,因为它不检查迭代器的提领是 否超界。</p>
 <a name="full_check"></a>
 <h4>full_check</h4>
<p> This policy has not been implemented yet. When it is, it will keep track of
-  all iterators and make sure that they are all valid.</p>
+ all iterators and make sure that they are all valid.<br>这个策略还未实 现。当它实现时,它会跟踪所有迭代器,并确保他们都是有效的。</p>
 <a name="predefined_storagepolicy_classes"></a>
-<h3>Predefined StoragePolicy classes</h3>
+<h3>Predefined StoragePolicy classes 预定义的存储策略类</h3>
 <a name="std_deque"></a>
 <h4>std_deque</h4>
<p> This policy keeps all buffered data in a std::deque. All data is stored as long as there is more than one iterator. Once the iterator count goes down to one, and the queue is no longer needed, it is cleared, freeing up memory. The - queue can also be forcibly cleared by calling multi_pass::clear_queue().</p> + queue can also be forcibly cleared by calling multi_pass::clear_queue().<br>这个策略将所有缓冲数据保存在一个 std::deque 中。只要有一个以上的迭代器,所有数据都要保存。一旦迭代器计数下降为一,这个队 列就不再需要了,它将被清除并释放内存。该队列也可以通过调用 multi_pass::clear_queue() 强行清除。</p>
 <a name="fixed_size_queue_lt_n_gt_"></a>
 <h4>fixed_size_queue&lt;N&gt;</h4>
<p> fixed_size_queue keeps a circular buffer that is size N+1 and stores N elements.
@@ -201,60 +227,80 @@
iterator is trailing too far behind and has become invalid. No dynamic allocation is done by this policy during normal iterator operation, only on initial construction. The memory usage of this StoragePolicy is set at N+1 bytes, unlike std_deque,
-  which is unbounded.</p>
+  which is unbounded.<br>fixed_size_queue
+保持一个大小这 N+1 的循环缓冲区,保存 N 个元素。fixed_size_queue 是一个模 板,有一个 std::size_t
+参数用于指定队列大小。你要负责确保 N
+对于你的分析器足够大。当最前的迭代器被递增时,缓冲区的最后字符将被自动删 除。当前没有办法得知一个迭代器是否落后得太多而变为无效。在普通的迭代器操 +作期间,该策略没有动态分配,除了在初始化构造期间。这个存储策略的内存开销被 设定为 N+1 字节,不象 std_deque 那样是无界的。</p>
 <a name="combinations__how_to_specify_your_own_custom_multi_pass"></a>
-<h2>Combinations: How to specify your own custom multi_pass</h2>
+<h2>Combinations: How to specify your own custom multi_pass 组合:如何指定 你自己的multi_pass</h2> <p> The beauty of policy based designs is that you can mix and match policies to create your own custom class by selecting the policies you want. Here's an example of how to specify a custom multi_pass that wraps an istream_iterator&lt;char&gt;, and is slightly more efficient than the default because it uses the first_owner
-  OwnershipPolicy and the no_check CheckingPolicy:</p>
+  OwnershipPolicy and the no_check CheckingPolicy:<br>基
+于策略的设计的好处在于,你可以混合及匹配不同的策略,通过选择你想要的策略来 创建你自己的定制策略。以下是一个关于如何指定一个定制 +multi_pass 的例子,它封装了一个 istream_iterator&lt;char&gt;,而且比缺省的 要高效一点,因为它使用了
+first_owner 所有权策略和 no_check 检查策略:</p>
<pre> <code><span class="keyword">typedef </span><span class="identifier">multi_pass</span><span class="special">&lt;<br> </span><span class="identifier">istream_iterator</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">input_iterator</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">first_owner</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">no_check</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">std_deque<br> </span><span class="special">&gt; </span><span class="identifier">first_owner_multi_pass_t</span><span class="special">;<br></span></code></pre> <p> The default template parameters for multi_pass are: input_iterator InputPolicy, ref_counted OwnershipPolicy, buf_id_check CheckingPolicy and std_deque StoragePolicy. So if you use multi_pass&lt;istream_iterator&lt;char&gt; &gt; you will get those
-  pre-defined behaviors while wrapping an istream_iterator&lt;char&gt;.</p>
+ pre-defined behaviors while wrapping an istream_iterator&lt;char&gt;.<br>multi_pass +的缺省模板参数是:input_iterator 输入策略,ref_counted 所有权策 略,buf_id_check 检查策略和 +std_deque 存储策略。所以,如果你使用 multi_pass&lt;istream_iterator&lt;char&gt; +&gt;,那么你将得到一个具有以上预定义行为的封装 istream_iterator&lt;char&gt;。</p> <p> There is one other pre-defined class called look_ahead. look_ahead has two template parameters: InputT, the type of the input iterator to wrap, and a std::size_t N, which specifies the size of the buffer to the fixed_size_queue policy. While the default multi_pass configuration is designed for safey, look_ahead is designed for speed. look_ahead is derived from a multi_pass with the following policies: input_iterator InputPolicy, first_owner OwnershipPolicy, no_check CheckingPolicy,
-  and fixed_size_queue&lt;N&gt; StoragePolicy.</p>
+  and fixed_size_queue&lt;N&gt; StoragePolicy.<br>还
+有一个名为 look_ahead 的预定义类。look_ahead 有两个模板参数:InputT 是要封 装的输入迭代器的类型,以及一个 +std::size_t N 用于指定 fixed_size_queue 策略所用的缓冲区的大小。缺省的 multi_pass +配置是为安全而设计的,而 look_ahead 则是为速度而设计的。look_ahead 派生自带 有以下策略的 +multi_pass:input_iterator 输入策略,first_owner 所有权策略,no_check 检查 策略和
+fixed_size_queue&lt;N&gt; 存储策略。</p>
<a name="how_to_write_a_functor_for_use_with_the_functor_input_inputpolicy"></a>
-<h3>How to write a functor for use with the functor_input InputPolicy</h3>
+<h3>How to write a functor for use with the functor_input InputPolicy 如何 编写一个与functor_input输入策略共用的仿函数</h3> <p> If you want to use the functor_input InputPolicy, you can write your own functor that will supply the input to multi_pass. The functor must satisfy two requirements. It must have a typedef result_type which specifies the return type of operator(). This is standard practice in the STL. Also, it must supply a static variable called eof which is compared against to know whether the input has reached the
-  end. Here is an example:</p>
+  end. Here is an example:<br>如
+果你想使用 functor_input 输入策略,你可以编写你自己的仿函数向 multi_pass
+提供输入。该仿函数必须满足两个条件。它必须有一个 typedef result_type 用于指 定 operator() +的返回类型。这是STL中的标准实践。另外,它必须提供一个名为 eof 的静态变量用 于比较以获知输入是否已到结尾。以下是一个例子:</p> <pre> <code><span class="keyword">class </span><span class="identifier">my_functor<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="keyword">typedef char </span><span class="identifier">result_type</span><span class="special">;<br><br> </span><span class="identifier">my_functor</span><span class="special">()<br> : </span><span class="identifier">c</span><span class="special">(</span><span class="literal">'A'</span><span class="special">) {}<br><br> </span><span class="keyword">char operator</span><span class="special">()() </span><span class="keyword">const<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">c </span><span class="special">== </span><span class="literal">'M'</span><span class="special">)<br> </span><span class="keyword">return </span><span class="identifier">eof</span><span class="special">;<br> </span><span class="keyword">else<br> return </span><span class="identifier">c</span><span class="special">++;<br> }<br><br> </span><span class="keyword">static </span><span class="identifier">result_type eof</span><span class="special">;<br><br> </span><span class="keyword">private</span><span class="special">:<br><br> </span><span class="keyword">char </span><span class="identifier">c</span><span class="special">;<br> };<br><br> </span><span class="identifier">my_functor</span><span class="special">::</span><span class="identifier">result_type my_functor</span><span class="special">::</span><span class="identifier">eof </span><span class="special">= </span><span class="literal">'\0'</span><span class="special">;<br><br> </span><span class="keyword">typedef </span><span class="identifier">multi_pass</span><span class="special">&lt;<br> </span><span class="identifier">my_functor</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">functor_input</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">first_owner</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">no_check</span><span class="special">,<br> </span><span class="identifier">multi_pass_policies</span><span class="special">::</span><span class="identifier">std_deque<br> </span><span class="special">&gt; </span><span class="identifier">functor_multi_pass_t</span><span class="special">;<br><br> </span><span class="identifier">functor_multi_pass_t first </span><span class="special">= </span><span class="identifier">functor_multi_pass_t</span><span class="special">(</span><span class="identifier">my_functor</span><span class="special">());<br> </span><span class="identifier">functor_multi_pass_t last</span><span class="special">;<br></span></code></pre>
 <a name="how_to_write_policies_for_use_with_multi_pass"></a>
-<h3>How to write policies for use with multi_pass</h3>
+<h3>How to write policies for use with multi_pass 如何编写用于multi_pass的 策略</h3>
 <a name="inputpolicy"></a>
-<h4>InputPolicy</h4>
-<p> An InputPolicy must have the following interface:</p>
-<pre> <code><span class="keyword">class </span><span class="identifier">my_input_policy </span><span class="comment">// your policy name<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// class inner will be instantiated with the type given<br> // as the InputT parameter to multi_pass.<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">InputT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">inner<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// these typedefs determine the iterator_traits for multi_pass<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">value_type</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">difference_type</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">pointer</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">reference</span><span class="special">;<br><br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">inner</span><span class="special">();<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">InputT </span><span class="identifier">x</span><span class="special">);<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// delete or clean up any state<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="comment">// return true if *this and x have the same input<br> </span><span class="keyword">bool </span><span class="identifier">same_input</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">inner</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br><br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// get an instance from the input<br> </span><span class="identifier">result_type </span><span class="identifier">get_input</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="comment">// advance the input<br> </span><span class="keyword">void </span><span class="identifier">advance_input</span><span class="special">();<br> </span><span class="comment">// return true if the input is at the end<br> </span><span class="keyword">bool </span><span class="identifier">input_at_eof</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};<br> </span><span class="special">};<br></span></code></pre>
+<h4>InputPolicy 输入策略</h4>
+<p> An InputPolicy must have the following interface:<br>输入策略必须具有以 下接口:</p> +<pre> <code><span class="keyword">class </span><span class="identifier">my_input_policy </span><span class="comment">// your policy name 你的策略名<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// class inner will be instantiated with the type given<br> // as the InputT parameter to multi_pass.<br> // 类inner以给定为multi_pass的InputT参数的类型进行实 例化<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">InputT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">inner<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// these typedefs determine the iterator_traits for multi_pass<br> // 以下typedef决定 multi_pass的iterator_traits<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">value_type</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">difference_type</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">pointer</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">x </span><span class="identifier">reference</span><span class="special">;<br><br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">inner</span><span class="special">();<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">InputT </span><span class="identifier">x</span><span class="special">);<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// delete or clean up any state 删除或清除所有状态<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="comment">// return true if *this and x have the same input 如果*this和x具有相同输入则返回 true<br> </span><span class="keyword">bool </span><span class="identifier">same_input</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">inner</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br><br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// get an instance from the input 从输入取出一 个实例<br> </span><span class="identifier">result_type </span><span class="identifier">get_input</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="comment">// advance the input 步进输入<br> </span><span class="keyword">void </span><span class="identifier">advance_input</span><span class="special">();<br> </span><span class="comment">// return true if the input is at the end 如果输入到尾则返回true<br> </span><span class="keyword">bool </span><span class="identifier">input_at_eof</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};<br> </span><span class="special">};<br></span></code></pre> <p> Because of the way that multi_pass shares a buffer and input among multiple copies, class inner should keep a pointer to it's input. The copy constructor should simply copy the pointer. destroy() should delete it. same_input should compare the pointers. For more details see the various implementations of InputPolicy
-  classes.</p>
+  classes.<br>由
+于 multi_pass 共享一个缓冲区并输入多份拷贝的方式,类 inner 应持有指向其输入 的指针。复制构造函数只需复制该指针。而 +destroy() 则 delete 它。 same_input 应比较这些指针。更多的细节请见 InputPolicy 类的各个实现。</p>
 <a name="ownershippolicy"></a>
-<h4>OwnershipPolicy</h4>
-<p> The OwnershipPolicy must have the following interface:</p>
-<pre> <code><span class="keyword">class </span><span class="identifier">my_ownership_policy<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">my_ownership_policy</span><span class="special">();<br> </span><span class="identifier">my_ownership_policy</span><span class="special">(</span><span class="identifier">my_ownership_policy </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// clone is called when a copy of the iterator is made<br> </span><span class="keyword">void </span><span class="identifier">clone</span><span class="special">();<br> </span><span class="comment">// called when a copy is deleted. Return true to indicate<br> // resources should be released<br> </span><span class="keyword">bool </span><span class="identifier">release</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">my_ownership_policy</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br><br> </span><span class="keyword">public</span><span class="special">:<br> </span><span class="comment">// returns true if there is only one iterator in existence.<br> // std_dequeue StoragePolicy will free it's buffered data if this<br> // returns true.<br> </span><span class="keyword">bool </span><span class="identifier">unique</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};<br></span></code></pre>
+<h4>OwnershipPolicy 所有权策略</h4>
+<p> The OwnershipPolicy must have the following interface:<br>所有权策略必 须具有以下接口:</p> +<pre> <code><span class="keyword">class </span><span class="identifier">my_ownership_policy<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">my_ownership_policy</span><span class="special">();<br> </span><span class="identifier">my_ownership_policy</span><span class="special">(</span><span class="identifier">my_ownership_policy </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// clone is called when a copy of the iterator is made 复制迭代器时调用clone<br> </span><span class="keyword">void </span><span class="identifier">clone</span><span class="special">();<br> </span><span class="comment">// called when a copy is deleted. Return true to indicate<br> // resources should be released<br> // 删除一个拷贝时调用。返回true表示资源应被释放 <br> </span><span class="keyword">bool </span><span class="identifier">release</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">my_ownership_policy</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br><br> </span><span class="keyword">public</span><span class="special">:<br> </span><span class="comment">// returns true if there is only one iterator in existence.<br> // std_dequeue StoragePolicy will free it's buffered data if this<br> // returns true.<br> // 如果只有一个迭代器存在则返回true。如果返回true则 std_dequeue存储策略将释放期缓冲数据<br> </span><span class="keyword">bool </span><span class="identifier">unique</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};<br></span></code></pre>
 <a name="checkingpolicy"></a>
-<h4>CheckingPolicy</h4>
-<p> The CheckingPolicy must have the following interface:</p>
-<pre> <code><span class="keyword">class </span><span class="identifier">my_check<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">my_check</span><span class="special">();<br> </span><span class="identifier">my_check</span><span class="special">(</span><span class="identifier">my_check </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">my_check</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// check should make sure that this iterator is valid<br> </span><span class="keyword">void </span><span class="identifier">check</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">clear_queue</span><span class="special">();<br> </span><span class="special">};<br></span></code></pre>
+<h4>CheckingPolicy 检查策略</h4>
+<p> The CheckingPolicy must have the following interface:<br>检查策略必须具 有以下接口:</p> +<pre> <code><span class="keyword">class </span><span class="identifier">my_check<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">my_check</span><span class="special">();<br> </span><span class="identifier">my_check</span><span class="special">(</span><span class="identifier">my_check </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">my_check</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// check should make sure that this iterator is valid 检查以确认该迭代器有效<br> </span><span class="keyword">void </span><span class="identifier">check</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">clear_queue</span><span class="special">();<br> </span><span class="special">};<br></span></code></pre>
 <a name="storagepolicy"></a>
-<h4>StoragePolicy</h4>
-<p> A StoragePolicy must have the following interface:</p>
-<pre> <code><span class="keyword">class </span><span class="identifier">my_storage_policy<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// class inner will be instantiated with the value_type from the InputPolicy<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ValueT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">inner<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">inner</span><span class="special">();<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// will be called from the destructor of the last iterator.<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">inner</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// This is called when the iterator is dereferenced. It's a template<br> // method so we can recover the type of the multi_pass iterator<br> // and access it.<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="identifier">ValueT </span><span class="identifier">dereference</span><span class="special">(</span><span class="identifier">MultiPassT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="comment">// This is called when the iterator is incremented. It's a template<br> // method so we can recover the type of the multi_pass iterator<br> // and access it.<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="keyword">void </span><span class="identifier">increment</span><span class="special">(</span><span class="identifier">MultiPassT</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">clear_queue</span><span class="special">();<br> </span><span class="comment">// called to determine whether the iterator is an eof iterator<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="keyword">bool </span><span class="identifier">is_eof</span><span class="special">(</span><span class="identifier">MultiPassT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="comment">// called by operator==<br> </span><span class="keyword">bool </span><span class="identifier">equal_to</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="comment">// called by operator&lt;<br> </span><span class="keyword">bool </span><span class="identifier">less_than</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">}; </span><span class="comment"> // class inner<br> </span><span class="special">};<br></span></code></pre>
+<h4>StoragePolicy 存储策略</h4>
+<p> A StoragePolicy must have the following interface:<br>存储策略必须具有 以下接口:</p> +<pre> <code><span class="keyword">class </span><span class="identifier">my_storage_policy<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// class inner will be instantiated with the value_type from the InputPolicy<br> // 类 inner将以输入策略的value_type来实例化<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ValueT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">inner<br> </span><span class="special">{<br> </span><span class="keyword">protected</span><span class="special">:<br><br> </span><span class="identifier">inner</span><span class="special">();<br> </span><span class="identifier">inner</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// will be called from the destructor of the last iterator. 从最后一个迭代器的析构函数 调用。<br> </span><span class="keyword">void </span><span class="identifier">destroy</span><span class="special">();<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">inner</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="comment">// This is called when the iterator is dereferenced. It's a template<br> // method so we can recover the type of the multi_pass iterator<br> // and access it.<br> // 在迭代器被提领时调用。它是一个模板方法,我们可以找回 multi_pass迭代器的类型并访问它。<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="identifier">ValueT </span><span class="identifier">dereference</span><span class="special">(</span><span class="identifier">MultiPassT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="comment">// This is called when the iterator is incremented. It's a template<br> // method so we can recover the type of the multi_pass iterator<br> // and access it.<br> // 在迭代器</span></code><code><span class="comment">被递 增时调用。它是一个模板方法,我们可以找回multi_pass迭代器的类型并访问它。 </span></code><code><span class="comment"> <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="keyword">void </span><span class="identifier">increment</span><span class="special">(</span><span class="identifier">MultiPassT</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">clear_queue</span><span class="special">();<br> </span><span class="comment">// called to determine whether the iterator is an eof iterator 调用以确定迭代器是否 eof<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">MultiPassT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="keyword">bool </span><span class="identifier">is_eof</span><span class="special">(</span><span class="identifier">MultiPassT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">mp</span><span class="special">);<br> </span><span class="comment">// called by operator== 由operator==调用 <br> </span><span class="keyword">bool </span><span class="identifier">equal_to</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="comment">// called by operator&lt; 由operator&lt;调用<br> </span><span class="keyword">bool </span><span class="identifier">less_than</span><span class="special">(</span><span class="identifier">inner </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">}; </span><span class="comment"> // class inner<br> </span><span class="special">};<br></span></code></pre> <p> A StoragePolicy is the trickiest policy to write. You should study and understand
-  the existing StoragePolicy classes before you try and write your own.</p>
+ the existing StoragePolicy classes before you try and write your own.<br>存储策略是最难编写的策略。你应该在尝试编写你自己的存储策略之前,认真 学习和弄明白已有的存储策略类。</p>
 <table border="0">
   <tbody><tr>
     <td width="10"><br>
@@ -266,7 +312,7 @@
 </tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2001-2002 Daniel C. Nuffer<br>
+<p class="copyright">Copyright © 2001-2002 Daniel C. Nuffer<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
=======================================
--- /trunk/libs/spirit/classic/doc/portability.html     Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/portability.html     Mon Oct 12 20:27:43 2009
@@ -1,48 +1,55 @@
-<html>
-<head>
-<title>Portability</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Portability</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Portability</b></font></td> - <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Portability 可移植性</b></font></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="includes.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="style_guide.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>Historically, Spirit supported a lot of compilers, including (to some extent) poorly conforming compilers such as VC6. Spirit v1.6.x will be the last release that will support older poorly conforming compilers. Starting from Spirit v1.8.0, ill conforming compilers will not be supported. If you are still using one of
-  these older compilers, you can still use Spirit v1.6.x.</p>
+  these older compilers, you can still use Spirit v1.6.x.<br>从
+历史上看,Spirit支持的编译器很多,包括(在某种程度上)对标准符合度较差的编 译器,如VC6。Spirit
+v1.6.x将是最后一个支持标准符合度差的编译器的版本。从Spirit
+v1.8.0起,将不再支持标准符合度差的编译器。如果您仍在使用这些旧的编译器之 一,您仍然可以使用Spirit v1.6.x.</p> <p>The reason why Spirit v1.6.x worked on old non-conforming compilers is that the authors laboriously took the trouble of searching for workarounds to make these compilers happy. The process takes a lot of time and energy, especially - when one encounters the dreaded ICE or &quot;Internal Compiler Error&quot;.
+  when one encounters the dreaded ICE or "Internal Compiler Error".
Sometimes searching for a single workaround takes days or even weeks. Sometimes, there are no known workarounds. This stifles progress a lot. And, as the library gets more progressive and takes on more advanced C++ techniques, the difficulty
-  is escalated to even new heights.</p>
+  is escalated to even new heights.<br>Spirit
+v1.6.x能与不符合标准的编译器一起工作的原因是,作者很辛苦地寻找解决方法来使 这些编译器接受。这个过程需要大量的时间和精力,尤其是当遇到可怕的 +ICE或“内部编译器错误”时。有时为了一个解决办法寻找需要几天甚至几个星期。有时 候甚至没有可变通的办法。这扼杀许多进步。此外,由于本库的进一步发
+展以及更先进的C++技术的需要,这种困难升级到了新的高度。</p>
<p>Spirit v1.6.x will still be supported. Maintenance will still happen and bug fixes will still be applied. There will still be active development for the back-porting of new features introduced in Spirit v1.8.0 (and Spirit 1.9.0) to lesser able compilers; hopefully, fueled by contributions from the community. We welcome active support from the C++ community, especially those with special
-  expertise on compilers such as older Borland and MSVC++ compilers.</p>
-<p>Spirit 1.8 has been tested to compile and run properly on these compilers:</p> + expertise on compilers such as older Borland and MSVC++ compilers.<br>Spirit +v1.6.x仍然会得到支持。维护仍然会继续,漏洞修补仍然适用。仍然会有积极发展的 Spirit v1.8.0(以及Spirit +1.9.0)中引入的新功能向后移植至能力较差的编译器;我们希望并得到了来自社会各 界的捐款。我们欢迎C++社区的积极支持,尤其是在那些老的
+Borland和MSVC等C++编译器方面有特殊专长的。</p>
+<p>Spirit 1.8 has been tested to compile and run properly on these compilers:<br>Spirit 1.8 已在以下编译器上通过测试并正确运行:</p>
 <ol>
   <li>g++ 3.1 and above</li>
   <li>Comeau 4.24.5 </li>
@@ -53,22 +60,21 @@
as it is or with minimal portability fixes here and there. Please inform us if your compiler is known to be ISO/ANSI conforming and is not in this list above. Feel free to post feedback to <a href="https://lists.sourceforge.net/lists/listinfo/spirit-general";>Spirit-general
-  mailing list</a> [Spirit-general@xxxxxxxxxxxxxxxxxxxxx].</p>
+ mailing list</a> [Spirit-general@xxxxxxxxxxxxxxxxxxxxx].<br>如果你的编译 器充分地符合标准,你就有机会只需要在这里或那里做最少的移植修改,就可以编译 Spirit。如果你的编译器已知是符合ISO/ANSI标准而没有在上面列出,请通知我们。请 随时将反馈发送到 <a href="https://lists.sourceforge.net/lists/listinfo/spirit-general";>Spirit-通 用邮件列表</a> [Spirit-general@xxxxxxxxxxxxxxxxxxxxx]。</p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="includes.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="style_guide.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/position_iterator.html Tue Mar 31 01:07:16 2009 +++ /trunk/libs/spirit/classic/doc/position_iterator.html Mon Oct 12 20:27:43 2009
@@ -1,119 +1,106 @@
-<html>
-<head>
-<title>Position Iterator</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Position Iterator</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Position
-      Iterator</b></font> </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Position
+      Iterator 位置迭代器</b></font> </td>
+ <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="file_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="debugging.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>Often, when writing a parser that is able to detect errors in the format of the input stream, we want it to communicate to the user where the error happened within that input. The classic example is when writing a compiler or interpreter that detects syntactical errors in the parsed program, indicating the line number - and maybe even the position within the line where the error was found.</p> + and maybe even the position within the line where the error was found.<br>通常,在编写一个可以检测输入流的格式错误的分析器时,我们会希望它可 以告知用户,错误发生于输入的何处。典型的例子是,在编写一个编译器或解释器,检 测到被分析程序中的语法错误时,可以指出错误发生的行号甚至在行中的位置。</p> <p> The class position_iterator is a tool provided within Spirit that allows parser writers to easily implement this functionality. The concept is quite simple: this class is an iterator wrapper that keeps track of the current position within the file, including current file, line and column. It requires a single template - parameter, which should be the type of the iterator that is to be wrapped.</p>
-<p> To use it, you'll need to add the following include:</p>
-<pre>
- <code><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>spirit</span><span class=special>/</span><span class=identifier>iterator</span><span class=special>/</span><span class=identifier>position_iterator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span></code></pre>
-<p> Or include all the iterators in Spirit:</p>
-<pre>
- <code><span class=preprocessor>#include </span><span class=special>&lt;</span><span class=identifier>boost</span><span class=special>/</span><span class=identifier>spirit</span><span class=special>/</span><span class=identifier>iterator</span><span class=special>.</span><span class=identifier>hpp</span><span class=special>&gt;</span></code></pre> + parameter, which should be the type of the iterator that is to be wrapped.<br>类 position_iterator 是Spirit内部提供的一个工具,它允许分析器作 者可以很轻易地实现以上功能。这个概念很简单:这个类是一个迭代器包装,它跟踪文 件中的当前位置,包含当前文件、行号和列数。它要求单个模板参数,即被封装的迭代 器类型。</p> +<p> To use it, you'll need to add the following include:<br>要使用它,你需 要添加以下头文件:</p> +<pre> <code><span class="preprocessor">#include </span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">position_iterator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></pre> +<p> Or include all the iterators in Spirit:<br>或包含Spirit的所有迭代 器:</p> +<pre> <code><span class="preprocessor">#include </span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code></pre> <p> To construct the wrapper, it needs both the begin and end iterators of the input sequence, and the file name of the input sequence. Optionally, you can also specify the starting line and column numbers, which default to 1. Default construction, with no parameters, creates a generic end-of-sequence iterator, in a similar manner as it's done in the stream operators of the standard C++
-  library.</p>
+ library.<br>为了构造该包装,它需要输入序列的 begin 和 end 迭代器,以及输 入序列的文件名。可选地,你也可以指定开始行号和列数,它们缺省为1。不带参数的 缺省构造将创建一个泛型的序列结束迭代器,这与标准C++库的流操作符中的方法类 似。</p> <p> The wrapped iterator must belong to the input or forward iterator category,
-  and the position_iterator just inherits that category.</p>
+ and the position_iterator just inherits that category.<br>被封装的迭代器 必须属于输入迭代器或前向迭代器种类,且 position_iterator 只是继承其种类。 </p> <p> For example, to create begin and end positional iterators from an input C-
-  string, you'd use:</p>
-<pre>
- <code><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>inputstring </span><span class=special>= </span><span class=string>&quot;...&quot;</span><span class=special>; - </span><span class=keyword>typedef </span><span class=identifier>position_iterator</span><span class=special>&lt;</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*&gt; </span><span class=identifier>iterator_t</span><span class=special>;
-
- </span><span class=identifier>iterator_t </span><span class=identifier>begin</span><span class=special>(</span><span class=identifier>inputstring</span><span class=special>, </span><span class=identifier>inputstring</span><span class=special>+</span><span class=identifier>strlen</span><span class=special>(</span><span class=identifier>inputstring</span><span class=special>)); - </span><span class=identifier>iterator_t </span><span class=identifier>end</span><span class=special>;</span></code></pre> + string, you'd use:<br>例如,从一个输入的C字符串创建 begin 和 end 位置迭代 器,你要用:</p> +<pre> <code><span class="keyword">char </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">inputstring </span><span class="special">= </span><span class="string">"..."</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">position_iterator</span><span class="special">&lt;</span><span class="keyword">char </span><span class="keyword">const</span><span class="special">*&gt; </span><span class="identifier">iterator_t</span><span class="special">;<br><br> </span><span class="identifier">iterator_t </span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">inputstring</span><span class="special">, </span><span class="identifier">inputstring</span><span class="special">+</span><span class="identifier">strlen</span><span class="special">(</span><span class="identifier">inputstring</span><span class="special">));<br> </span><span class="identifier">iterator_t </span><span class="identifier">end</span><span class="special">;</span></code></pre>
 <a name="operations"></a>
-<h2>Operations</h2>
-<pre>
- <code><span class=keyword>void </span><span class=identifier>set_position</span><span class=special>(</span><span class=identifier>file_position </span><span class=keyword>const</span><span class=special>&amp;);</span></code></pre>
+<h2>Operations 操作</h2>
+<pre> <code><span class="keyword">void </span><span class="identifier">set_position</span><span class="special">(</span><span class="identifier">file_position </span><span class="keyword">const</span><span class="special">&amp;);</span></code></pre> <p> Call this function when you need to change the current position stored in the iterator. For example, if parsing C-style #include directives, the included file's input must be marked by restarting the file and column to 1 and 1 and
-  the name to the new file's name.<br>
+ the name to the new file's name.<br>当你需要改变保存在迭代器中的位置 时,调用这个函数。例如,如果要分析C风格的 #include 指示符,被包含的文件必须 被标记为重新开始一个文件,且行号、列数为1,文件名为新的文件名。<br>
 </p>
-<pre>
- <code><span class=identifier>file_position </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>get_position</span><span class=special>() </span><span class=keyword>const</span><span class=special>;</span></code></pre>
-<p> Call this function to retrieve the current position.</p>
-<pre>
- <code><span class=keyword>void </span><span class=identifier>set_tabchars</span><span class=special>(</span><span class=keyword>int</span><span class=special>);</span></code></pre> +<pre> <code><span class="identifier">file_position </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">get_position</span><span class="special">() </span><span class="keyword">const</span><span class="special">;</span></code></pre> +<p> Call this function to retrieve the current position.<br>调用该函数以取 出当前位置。</p> +<pre> <code><span class="keyword">void </span><span class="identifier">set_tabchars</span><span class="special">(</span><span class="keyword">int</span><span class="special">);</span></code></pre> <p> Call this to set the number of tabs per character. This value is necessary
-  to correctly track the column number.<br>
+ to correctly track the column number.<br>调用此函数以设置制表符的字符数 量。该值对于正确跟踪列数是必需的。<br>
 </p>
 <p> <a name="file_position"></a> </p>
 <h2>file_position</h2>
<p> file_position is a structure that holds the position within a file. Its fields
-  are:</p>
-<table width="90%" border="0" align="center">
-  <tr>
+  are:<br>file_position 是一个保存了文件内部位置的结构。它的字段有:</p>
+<table align="center" border="0" width="90%">
+  <tbody><tr>
     <td class="table_title" colspan="2">file_position fields</td>
   </tr>
   <tr>
- <td class="table_cells" width="26%"><code><span class=identifier>std</span><span class=special>::</span><span class=identifier>string - </span><span class=identifier>file</span><span class=special>;</span></code></td> - <td class="table_cells" width="74%">Name of the file. Hopefully a full pathname</td> + <td class="table_cells" width="26%"><code><span class="identifier">std</span><span class="special">::</span><span class="identifier">string + </span><span class="identifier">file</span><span class="special">;</span></code></td> + <td class="table_cells" width="74%">Name of the file. Hopefully a full pathname <br>文件名。希望是全路径名</td>
   </tr>
   <tr>
- <td class="table_cells" width="26%"><code><span class=keyword>int</span><span class=identifier>
-      line</span><span class=special>;</span></code></td>
+ <td class="table_cells" width="26%"><code><span class="keyword">int</span><span class="identifier">
+      line</span><span class="special">;</span></code></td>
<td class="table_cells" width="74%">Line number within the file. By default,
-      the first line is number 1</td>
+ the first line is number 1<br>文件内的行号。缺省地,第一行行号为 1</td>
   </tr>
   <tr>
- <td class="table_cells" width="26%"><code><span class=keyword>int </span><span class=identifier>column</span><span class=special>;</span></code></td> + <td class="table_cells" width="26%"><code><span class="keyword">int </span><span class="identifier">column</span><span class="special">;</span></code></td> <td class="table_cells" width="74%">Column position within the file. The first
-      column is 1</td>
+      column is 1<br>文件内的列位置。第一列为1</td>
   </tr>
-</table>
-<p><img src="theme/lens.gif" width="15" height="16"> See <a href="../example/fundamental/position_iterator/position_iterator.cpp">position_iterator.cpp</a> for a compilable example. This is part of the Spirit distribution.</p>
+</tbody></table>
+<p><img src="theme/lens.gif" height="16" width="15"> See <a href="../example/fundamental/position_iterator/position_iterator.cpp">position_iterator.cpp</a> for a compilable example. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 可编译的例子请见 <a href="../example/fundamental/position_iterator/position_iterator.cpp">position_iterator.cpp</a>。 这是Spirit发布包的一部分。</p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="file_iterator.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="debugging.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2002 Juan Carlos Arevalo-Baeza<br>
+<p class="copyright">Copyright © 2002 Juan Carlos Arevalo-Baeza<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt) </font> </p>
 <p class="copyright">&nbsp; </p>
 <p>&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/quickref.html        Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/quickref.html        Mon Oct 12 20:27:43 2009
@@ -1,253 +1,249 @@
-<html>
-
-<head>
-<title>Quick Reference</title>
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type">
+
+<title>Quick Reference</title><link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10"> </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Quick
-      Reference </b></font></td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Quick
+      Reference 快速参考 </b></font></td>
+ <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="error_handling.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="includes.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>This isn't intended to be a full, detailed reference; nor is it intended to be of any use to readers who aren't already familiar with Spirit. It's just a brief reminder of the syntax and behaviour of each component, with links to
-  the full documentation. </p>
+ the full documentation.<br>本章的目的不是给出一个完整、详尽的参考手册;也 不是给那些对Spirit还不熟悉的读者使用的。它只是对语法及各个组件行为的简要提 醒,以及到完整文档的链接。 </p>
 <ul>
<li><strong>Primitive parser generators</strong> <i>(action arguments are listed
-    on the right)</i>
+ on the right)</i><strong> 基本分析器生成器</strong><i>(动作参数在右侧列 出)</i>
     <ul>
-      <li><a href="quickref.html#null_parsers">Null parsers</a></li>
- <li><a href="quickref.html#character_parsers">Character parsers</a></li>
-      <li><a href="quickref.html#number_parsers">Number parsers</a></li>
- <li><a href="quickref.html#otherlexeme_parsers">Other lexeme parsers</a></li>
-      <li><a href="quickref.html#text_parsers">Text parsers</a><br>
+ <li><a href="quickref.html#null_parsers">Null parsers 空分析器 </a></li> + <li><a href="quickref.html#character_parsers">Character parsers 字符 分析器</a></li> + <li><a href="quickref.html#number_parsers">Number parsers 数字分析器 </a></li> + <li><a href="quickref.html#otherlexeme_parsers">Other lexeme parsers 其它词位分析器</a></li> + <li><a href="quickref.html#text_parsers">Text parsers 文本分析器 </a><br>
         <br>
       </li>
     </ul>
   </li>
-  <li><strong>Other parser elements</strong>
+  <li><strong>Other parser elements 其它分析器元素</strong>
     <ul>
- <li><a href="quickref.html#compound_parsers">Compound parsers</a></li> - <li><a href="quickref.html#general_directives">General directives</a></li> - <li><a href="quickref.html#tree_specific_directives">Tree-specific directives</a><br> + <li><a href="quickref.html#compound_parsers">Compound parsers 复合分 析器</a></li> + <li><a href="quickref.html#general_directives">General directives 通 用指示符</a></li> + <li><a href="quickref.html#tree_specific_directives">Tree-specific directives 树专用的指示符</a><br>
         <br>
       </li>
     </ul>
   </li>
-  <li><strong>Operators</strong>
+  <li><strong>Operators 操作符</strong>
     <ul>
-      <li><a href="quickref.html#unary_operators">Unary operators</a></li>
- <li><a href="quickref.html#binary_operators">Binary operators</a> <i>(in order of precedence)<br>
-        </i></li>
+ <li><a href="quickref.html#unary_operators">Unary operators 单参操作 符</a></li> + <li><a href="quickref.html#binary_operators">Binary operators</a> <i>(in order of precedence) </i><a href="quickref.html#binary_operators">二 元操作符</a><i>(按优先级顺序排)</i></li>
     </ul>
   </li>
 </ul>

 <table>

-    <tr>
+    <tbody><tr>

         <td valign="top">

             <table>

-                <tr>
- <td class="table_title" colspan="3" id="null_parsers"><a name="null_parsers"></a>Null parsers</td>
+                <tbody><tr>
+ <td class="table_title" colspan="3" id="null_parsers"><a name="null_parsers"></a>Null parsers 空分析器</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">end_p</a></code></td>
-                    <td class="table_cells">Matches EOF</td>
+                    <td class="table_cells">Matches EOF<br>匹配EOF</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>
- <td class="table_cells"><code><a href="primitives.html">eps_p</a><br /> + <td class="table_cells"><code><a href="primitives.html">eps_p</a><br>
             <a href="primitives.html">eps_p</a>(P)</code></td>
- <td class="table_cells">Matches without consuming text</td> + <td class="table_cells">Matches without consuming text<br>匹配且不消耗文本</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>
- <td class="table_cells"><code><a href="primitives.html">epsilon_p</a><br /> + <td class="table_cells"><code><a href="primitives.html">epsilon_p</a><br>
             <a href="primitives.html">epsilon_p</a>(P)</code></td>
-                    <td class="table_cells">Synonym for <b>eps_p</b></td>
+ <td class="table_cells">Synonym for <b>eps_p<br></b> <b>eps_p</b>的同义词<b></b></td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">nothing_p</a></code></td>
-                    <td class="table_cells">Always fails</td>
+ <td class="table_cells">Always fails<br>总是匹配失败 </td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="3" id="character_parsers"><a name="character_parsers" id="character_parsers"></a>Character parsers</td> + <td class="table_title" colspan="3" id="character_parsers"><a name="character_parsers" id="character_parsers"></a>Character parsers 字符分析器</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">alnum_p</a></code></td> - <td class="table_cells">Matches any alphanumeric character</td> + <td class="table_cells">Matches any alphanumeric character<br>匹配任意字母和数字</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">alpha_p</a></code></td>
-                    <td class="table_cells">Matches any letter</td>
+ <td class="table_cells">Matches any letter<br>匹配任意 字母</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">anychar_p</a></code></td>
-                    <td class="table_cells">Matches any character</td>
+ <td class="table_cells">Matches any character<br>匹配任 意字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">blank_p</a></code></td>
-                    <td class="table_cells">Matches a space or tab</td>
+ <td class="table_cells">Matches a space or tab<br>匹配 一个空格或制表符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="primitives.html">ch_p</a>(char)</code></td>
-                    <td class="table_cells">Matches a character</td>
+ <td class="table_cells">Matches a character<br>匹配一个 字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="character_sets.html">chset_p</a>(charset)</code></td> - <td class="table_cells">Matches a character in the set</td> + <td class="table_cells">Matches a character in the set<br>匹配字符集中的某个字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">cntrl_p</a></code></td> - <td class="table_cells">Matches any control character</td> + <td class="table_cells">Matches any control character<br>匹配任意控制字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">digit_p</a></code></td>
-                    <td class="table_cells">Matches any digit</td>
+ <td class="table_cells">Matches any digit<br>匹配任意数 字</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="parametric_parsers.html">f_ch_p</a>(func)</code></td>
-                    <td class="table_cells">Matches a character</td>
+ <td class="table_cells">Matches a character<br>匹配一个 字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="parametric_parsers.html">f_range_p</a>(func1,
             func2)</code></td>
- <td class="table_cells">Matches any character in the inclusive range</td> + <td class="table_cells">Matches any character in the inclusive range<br>匹配闭区间内的任意字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">graph_p</a></code></td> - <td class="table_cells">Matches any non-space printable character</td> + <td class="table_cells">Matches any non-space printable character<br>匹配任意非空可打印字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">lower_p</a></code></td> - <td class="table_cells">Matches any lower-case letter</td> + <td class="table_cells">Matches any lower-case letter<br>匹配任意小写字母</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">print_p</a></code></td> - <td class="table_cells">Matches any printable character</td> + <td class="table_cells">Matches any printable character<br>匹配任意可打印字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">punct_p</a></code></td> - <td class="table_cells">Matches any punctuation mark</td> + <td class="table_cells">Matches any punctuation mark<br>匹配任意标点符号</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="primitives.html">range_p</a>(char1,
             char2)</code></td>
- <td class="table_cells">Matches any character in the inclusive range</td> + <td class="table_cells">Matches any character in the inclusive range<br>匹配闭区间内的任意字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">sign_p</a></code></td> - <td class="table_cells">Matches a plus or minus sign</td> + <td class="table_cells">Matches a plus or minus sign<br>匹配正号或负号</td>
                     <td class="table_cells"><i>bool</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">space_p</a></code></td> - <td class="table_cells">Matches any whitespace character</td> + <td class="table_cells">Matches any whitespace character<br>匹配任意空白字符</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">upper_p</a></code></td> - <td class="table_cells">Matches any upper-case letter</td> + <td class="table_cells">Matches any upper-case letter<br>匹配任意大写字母</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">xdigit_p</a></code></td> - <td class="table_cells">Matches any hexadecimal digit</td> + <td class="table_cells">Matches any hexadecimal digit<br>匹配任意十六进制数字</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="3" id="number_parsers"><a name="number_parsers"></a>Number parsers</td> + <td class="table_title" colspan="3" id="number_parsers"><a name="number_parsers"></a>Number parsers 数字分析器 </td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">bin_p</a></code></td> - <td class="table_cells">Matches an unsigned binary integer</td> + <td class="table_cells">Matches an unsigned binary integer<br>匹配一个无符号二进制整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">hex_p</a></code></td> - <td class="table_cells">Matches an unsigned hexadecimal integer</td> + <td class="table_cells">Matches an unsigned hexadecimal integer<br>匹配一个无符号十六进制整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">int_p</a></code></td> - <td class="table_cells">Matches a signed decimal integer</td> + <td class="table_cells">Matches a signed decimal integer<br>匹配一个有符号十进制整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="numerics.html">int_parser</a>&lt;type,
             base, min, max&gt;</code></td>
- <td class="table_cells">Matches a signed integer with <b>min</b> to <b>max</b> digits</td> + <td class="table_cells">Matches a signed integer with <b>min</b> to <b>max</b> digits<br>匹配 <b>min</b> 至 <b>max</b> 间的有符号 整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">oct_p</a></code></td> - <td class="table_cells">Matches an unsigned octal integer</td> + <td class="table_cells">Matches an unsigned octal integer<br>匹配一个无符号八进制整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">real_p</a></code></td> - <td class="table_cells">Matches a floating point number</td> + <td class="table_cells">Matches a floating point number<br>匹配一个浮点数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="numerics.html">real_parser</a>&lt;type,
             policy&gt;</code></td>
- <td class="table_cells">Matches a floating point number</td> + <td class="table_cells">Matches a floating point number<br>匹配一个浮点数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">strict_real_p</a></code></td> - <td class="table_cells">Matches a floating point number (requires decimal point)</td> + <td class="table_cells">Matches a floating point number (requires decimal point)<br>匹配一个浮点数(要求小数点)</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">strict_ureal_p</a></code></td> - <td class="table_cells">Matches an unsigned FP number (requires decimal point)</td> + <td class="table_cells">Matches an unsigned FP number (requires decimal point)<br>匹配一个无符号浮点数(要求小数点)</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
@@ -259,80 +255,80 @@

<td class="table_cells"><code><a href="numerics.html">uint_parser</a>&lt;type,
             base, min, max&gt;</code></td>
- <td class="table_cells">Matches an unsigned integer with <b>min</b> to <b>max</b> digits</td> + <td class="table_cells">Matches an unsigned integer with <b>min</b> to <b>max</b> digits<br>匹配 <b>min</b> 至 <b>max</b> 间的无 符号整数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="numerics.html">ureal_p</a></code></td> - <td class="table_cells">Matches an unsigned FP number</td> + <td class="table_cells">Matches an unsigned FP number<br>匹配一个无符号浮点数</td>
                     <td class="table_cells"><i>numeric</i></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="3" id="other_lexeme_parsers"><a name="otherlexeme_parsers"></a>Other lexeme parsers</td> + <td class="table_title" colspan="3" id="other_lexeme_parsers"><a name="otherlexeme_parsers"></a>Other lexeme parsers 其它词位分析器</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="escape_char_parser.html">c_escape_ch_p</a></code></td>
-                    <td class="table_cells">Matches a C escape code</td>
+ <td class="table_cells">Matches a C escape code<br>匹配 一个C的转义代码</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

- <td class="table_cells"><code><a href="confix.html">comment_p</a>(string)<br /> + <td class="table_cells"><code><a href="confix.html">comment_p</a>(string)<br> <a href="confix.html">comment_p</a> (string1, string2)</code></td> - <td class="table_cells">Matches C++ or C-style comments</td> + <td class="table_cells">Matches C++ or C-style comments<br>匹配C++或C风格的注释</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="primitives.html">eol_p</a></code></td> - <td class="table_cells">Matches CR, LF, or any combination</td> + <td class="table_cells">Matches CR, LF, or any combination<br>匹配 CR, LF 或其任意组合</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="parametric_parsers.html">f_str_p</a>(func1,
             func2)</code></td>
-                    <td class="table_cells">Matches a string</td>
+ <td class="table_cells">Matches a string<br>匹配一个字 符串</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="escape_char_parser.html">lex_escape_ch_p</a></code></td> - <td class="table_cells">Matches a C escape code or any backslash escape</td> + <td class="table_cells">Matches a C escape code or any backslash escape<br>匹配一个C的转义代码或任意反斜杠转义</td>
                     <td class="table_cells"><i>char</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="regular_expression_parser.html">regex_p</a>(regex)</code></td> - <td class="table_cells">Matches a regular expression</td> + <td class="table_cells">Matches a regular expression<br>匹配一个正则表达式</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>

- <td class="table_cells"><code><a href="primitives.html">str_p</a>(string)<br /> + <td class="table_cells"><code><a href="primitives.html">str_p</a>(string)<br>
             <a href="primitives.html">str_p</a>(iter1, iter2)</code></td>
-                    <td class="table_cells">Matches a string</td>
+ <td class="table_cells">Matches a string<br>匹配一个字 符串</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="3" id="text_parsers"><a name="text_parsers"></a>Text parsers</td> + <td class="table_title" colspan="3" id="text_parsers"><a name="text_parsers"></a>Text parsers 文本分析器</td>
                 </tr>
                 <tr>

- <td class="table_cells"><code><a href="primitives.html">chseq_p</a>(string)<br /> + <td class="table_cells"><code><a href="primitives.html">chseq_p</a>(string)<br>
             <a href="primitives.html">chseq_p</a>(iter1, iter2)</code></td>
- <td class="table_cells">Matches a string, possibly with embedded whitespace</td> + <td class="table_cells">Matches a string, possibly with embedded whitespace<br>匹配一个字符串,可以带有内嵌的空白</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="parametric_parsers.html">f_chseq_p</a>(func1,
             func2)</code></td>
- <td class="table_cells">Matches a string, possibly with embedded whitespace</td> + <td class="table_cells">Matches a string, possibly with embedded whitespace<br>匹配一个字符串,可以带有内嵌的空白</td>
                     <td class="table_cells"><i>iter,iter</i></td>
                 </tr>

-            </table>
+            </tbody></table>

         </td>

@@ -342,261 +338,259 @@

             <table>

-                <tr>
- <td class="table_title" colspan="2" id="compound_parsers"><a name="compound_parsers"></a>Compound parsers</td>
+                <tbody><tr>
+ <td class="table_title" colspan="2" id="compound_parsers"><a name="compound_parsers"></a>Compound parsers 复合分 析器</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="confix.html">confix_p</a>(open,
             exp, close)</code></td>
- <td class="table_cells">Matches <b>open &gt;&gt; (exp - close) &gt;&gt; close</b></td> + <td class="table_cells">Matches <b>open &gt;&gt; (exp - close) &gt;&gt; close<br></b>匹配 <b>open &gt;&gt; (exp - close) &gt;&gt; close</b></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="dynamic_parsers.html">do_p</a>[P].<a href="dynamic_parsers.html">while_p</a>(cond)</code></td> - <td class="table_cells">Matches while a condition is true (at least once)</td> + <td class="table_cells">Matches while a condition is true (at least once)<br>当条件为真时匹配(至少一次)</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="dynamic_parsers.html">for_p</a>(init,
             cond, step)[P]</code></td>
-                    <td class="table_cells">Matches in a loop</td>
+ <td class="table_cells">Matches in a loop<br>在循环中匹 配</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="functor_parser.html">functor_parser</a>&lt;func&gt;</code></td>
-                    <td class="table_cells">Wraps an external parser</td>
+ <td class="table_cells">Wraps an external parser<br>封 装一个外部分析器</td>
                 </tr>
                 <tr>

- <td class="table_cells"><code><a href="dynamic_parsers.html">if_p</a>(cond)[P]<br /> + <td class="table_cells"><code><a href="dynamic_parsers.html">if_p</a>(cond)[P]<br> <a href="dynamic_parsers.html">if_p</a>(cond)[P].<a href="dynamic_parsers.html">else_p</a>[P]</code></td> - <td class="table_cells">Matches depending on a condition</td> + <td class="table_cells">Matches depending on a condition<br>根据条件进行匹配</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="the_lazy_parser.html">lazy_p</a>(P)</code></td> - <td class="table_cells">Evaluates a parser at run time</td> + <td class="table_cells">Evaluates a parser at run time<br>运行期对分析器求值</td>
                 </tr>
                 <tr>
- <td class="table_cells"><code><a href="list_parsers.html">list_p</a> <br />
-            <a href="list_parsers.html">list_p</a>(del)<br />
-            <a href="list_parsers.html">list_p</a>(item, del)<br />
+ <td class="table_cells"><code><a href="list_parsers.html">list_p</a> <br>
+            <a href="list_parsers.html">list_p</a>(del)<br>
+            <a href="list_parsers.html">list_p</a>(item, del)<br>
<a href="list_parsers.html">list_p</a>(item, del, end)</code></td>
-                    <td class="table_cells">Matches a delimited list</td>
+ <td class="table_cells">Matches a delimited list<br>匹 配一个带分隔符的列表</td>
                 </tr>
                 <tr>

- <td class="table_cells"><code><a href="loops.html">repeat_p</a>(num)[P]<br />
-            <a href="loops.html">repeat_p</a>(min, max)[P]<br />
+ <td class="table_cells"><code><a href="loops.html">repeat_p</a>(num)[P]<br>
+            <a href="loops.html">repeat_p</a>(min, max)[P]<br>
<a href="loops.html">repeat_p</a>(min, <a href="loops.html">more</a>)[P]</code></td>
-                    <td class="table_cells">Matches multiple times</td>
+ <td class="table_cells">Matches multiple times<br>多次 匹配</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="dynamic_parsers.html">while_p</a> (cond) [P]</code></td> - <td class="table_cells">Matches while a condition is true</td> + <td class="table_cells">Matches while a condition is true<br>当条件为真时匹配</td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="2" id="general_directives"><a name="general_directives"></a>General directives</td> + <td class="table_title" colspan="2" id="general_directives"><a name="general_directives"></a>General directives 通用指示符</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">as_lower_d</a>[P]</code></td> - <td class="table_cells">Converts text to lower case before matching</td> + <td class="table_cells">Converts text to lower case before matching<br>在匹配前将文本转换为小写</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="refactoring.html">attach_action_d</a>[(P1
             op P2)[act]]</code></td>
- <td class="table_cells">Transforms to <b>P1 [act] op P2 [act]</b></td> + <td class="table_cells">Transforms to <b>P1 [act] op P2 [act]<br></b>变换为 <b>P1 [act] op P2 [act]</b></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">lexeme_d</a>[P]</code></td> - <td class="table_cells">Turns off whitespace skipping</td> + <td class="table_cells">Turns off whitespace skipping<br>关闭空白符跳过</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">limit_d</a>[P](min,
             max)</code></td>
- <td class="table_cells">Matches only if the value is within the range</td> + <td class="table_cells">Matches only if the value is within the range<br>仅当值在区间内匹配</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">longest_d</a>[P]</code></td> - <td class="table_cells">Matches the longest of alternatives</td> + <td class="table_cells">Matches the longest of alternatives<br>匹配最长的选择</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">max_limit_d</a>[P](max)</code></td> - <td class="table_cells">Matches only if <b>value &lt;= max</b></td> + <td class="table_cells">Matches only if <b>value &lt;= max<br></b>仅当 <b>value &lt;= max</b> 时匹配<b></b></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">min_limit_d</a>[P](min)</code></td> - <td class="table_cells">Matches only if <b>value &gt;= min</b></td> + <td class="table_cells">Matches only if <b>value &gt;= min</b><b><br></b>仅当 <b>value &gt;= min</b> 时匹配</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="refactoring.html">refactor_action_d</a>[P1
             [act] op P2]</code></td>
- <td class="table_cells">Transforms to <b>(P1 op P2) [act]</b></td> + <td class="table_cells">Transforms to <b>(P1 op P2) [act]<br></b>变换为 <b>(P1 op P2) [act]</b></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="refactoring.html">refactor_unary_d</a>[op1
             P1 op2 P2]</code></td>
- <td class="table_cells">Transforms to <b>op1 (P1 op2 P2)</b></td> + <td class="table_cells">Transforms to <b>op1 (P1 op2 P2)<br></b>变换为 <b>op1 (P1 op2 P2)</b></td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="scoped_lock.html">scoped_lock_d</a>[P](mutex)</code></td> - <td class="table_cells">Locks a mutex while matching</td> + <td class="table_cells">Locks a mutex while matching<br>匹配时锁住一个互斥体</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="directives.html">shortest_d</a>[P]</code></td> - <td class="table_cells">Matches the shortest of alternatives</td> + <td class="table_cells">Matches the shortest of alternatives<br>匹配最短的选择</td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="2" id="tree_specific_directives"><a name="tree_specific_directives"></a>Tree-specific directives</td> + <td class="table_title" colspan="2" id="tree_specific_directives"><a name="tree_specific_directives"></a>Tree-specific directives 树专用的指示符 </td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">access_node_d</a>[P]</code></td> - <td class="table_cells">Passes node value to action</td> + <td class="table_cells">Passes node value to action<br>传递节点值至动作</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">discard_first_node_d</a>[P]</code></td>
-                    <td class="table_cells">Discards first node</td>
+ <td class="table_cells">Discards first node<br>丢弃第一 个节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">discard_last_node_d</a>[P]</code></td>
-                    <td class="table_cells">Discards last node</td>
+ <td class="table_cells">Discards last node<br>丢弃最后 一个节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">discard_node_d</a>[P]</code></td> - <td class="table_cells">Discards the generated node</td> + <td class="table_cells">Discards the generated node<br>丢弃生成的节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">infix_node_d</a>[P]</code></td> - <td class="table_cells">Discards even-position nodes</td> + <td class="table_cells">Discards even-position nodes<br>丢弃偶数位置的节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">inner_node_d</a>[P]</code></td> - <td class="table_cells">Discards first and last nodes</td> + <td class="table_cells">Discards first and last nodes<br>丢弃第一个和最后一个节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">leaf_node_d</a>[P]</code></td> - <td class="table_cells">Generates a single node with no children</td> + <td class="table_cells">Generates a single node with no children<br>生成不带子节点的单个节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">no_node_d</a>[P]</code></td>
-                    <td class="table_cells">Does not generate a node</td>
+ <td class="table_cells">Does not generate a node<br>不 生成节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">root_node_d</a>[P]</code></td> - <td class="table_cells">Identifies root nodes for an AST</td> + <td class="table_cells">Identifies root nodes for an AST<br>为AST标识根节点</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="trees.html">token_node_d</a>[P]</code></td> - <td class="table_cells">Synonym for <b>leaf_node_d</b></td> + <td class="table_cells">Synonym for <b>leaf_node_d<br></b> <b>leaf_node_d</b> 的同义词<b></b></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="2" id="unary_operators"><a name="unary_operators"></a>Unary operators</td> + <td class="table_title" colspan="2" id="unary_operators"><a name="unary_operators"></a>Unary operators 单参操作 符</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="operators.html">!P</a></code></td> - <td class="table_cells">Matches <b>P</b> or an empty string</td> + <td class="table_cells">Matches <b>P</b> or an empty string<br>匹配 <b>P</b> 或空串</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="operators.html">*P</a></code></td> - <td class="table_cells">Matches <b>P</b> zero or more times</td> + <td class="table_cells">Matches <b>P</b> zero or more times<br>匹配 <b>P</b> 零次或多次</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="operators.html">+P</a></code></td> - <td class="table_cells">Matches <b>P</b> one or more times</td> + <td class="table_cells">Matches <b>P</b> one or more times<br>匹配 <b>P</b> 一次或多次</td>
                 </tr>
                 <tr>

<td class="table_cells"><code><a href="primitives.html">~P</a></code></td> - <td class="table_cells">Matches anything that does not match <b>P</b></td> + <td class="table_cells">Matches anything that does not match <b>P<br></b>匹配任何不匹配 <b>P</b> 的文本<b></b></td>
                 </tr>

                 <tr>
- <td class="table_title" colspan="2" id="binary_operators"><a name="binary_operators"></a>Binary operators</td> + <td class="table_title" colspan="2" id="binary_operators"><a name="binary_operators"></a>Binary operators 二元操 作符</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 % P2</a></code></td> - <td class="table_cells">Matches one or more <b>P1</b> separated by <b>P2</b></td> + <td class="table_cells">Matches one or more <b>P1</b> separated by <b>P2<br></b>匹配一次或多次 <b>P1</b>,以 <b>P2</b> 分隔 <b></b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 - P2</a></code></td> - <td class="table_cells">Matches <b>P1</b> but not <b>P2</b></td> + <td class="table_cells">Matches <b>P1</b> but not <b>P2<br></b>匹配 <b>P1</b> 但不匹配 <b>P2</b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 &gt;&gt; P2</a></code></td> - <td class="table_cells">Matches <b>P1</b> followed by <b>P2</b></td> + <td class="table_cells">Matches <b>P1</b> followed by <b>P2<br></b>匹配 <b>P1</b> 后随 <b>P2</b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 &amp; P2</a></code></td> - <td class="table_cells">Matches both <b>P1</b> and <b>P2</b></td> + <td class="table_cells">Matches both <b>P1</b> and <b>P2<br></b>同时匹配 <b>P1</b> 和 <b>P2</b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 ^ P2</a></code></td> - <td class="table_cells">Matches <b>P1</b> or <b>P2</b>, but not both</td> + <td class="table_cells">Matches <b>P1</b> or <b>P2</b>, but not both<br>匹配 <b>P1</b> 或 <b>P2</b>,但不能同时匹配</td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 | P2</a></code></td> - <td class="table_cells">Matches <b>P1</b> or <b>P2</b></td> + <td class="table_cells">Matches <b>P1</b> or <b>P2<br></b>匹配 <b>P1</b> 或 <b>P2</b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 &amp;&amp; P2</a></code></td> - <td class="table_cells">Synonym for <b>P1 &gt;&gt; P2</b></td> + <td class="table_cells">Synonym for <b>P1 &gt;&gt; P2<br></b> <b>P1 &gt;&gt; P2</b> 的同义词<b></b></td>
                 </tr>
                 <tr>
<td class="table_cells"><code><a href="operators.html">P1 || P2</a></code></td> - <td class="table_cells">Matches <b>P1 | P2 | P1 &gt;&gt; P2</b></td> + <td class="table_cells">Matches <b>P1 | P2 | P1 &gt;&gt; P2<br></b>匹配 <b>P1 | P2 | P1 &gt;&gt; P2</b></td>
                 </tr>

-            </table>
+            </tbody></table>

         </td>

     </tr>

-</table>
+</tbody></table>

 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="error_handling.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="includes.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2003 Ross Smith<br>
+<p class="copyright">Copyright © 2003 Ross Smith<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p>&nbsp;</p>
-</body>
-
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/rationale.html       Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/rationale.html       Mon Oct 12 20:27:43 2009
@@ -1,88 +1,87 @@
-<html>
-<head>
-<title>Rationale</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Rationale</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Rationale</b></font></td> - <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Rationale 基本原理</b></font></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="faq.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="acknowledgments.html"><img src="theme/r_arr.gif" border="0"></a></td>
    </tr>
-</table>
-<p><img src="theme/lens.gif" width="15" height="16"> <strong>Virtual functions:
-  From static to dynamic C++</strong></p>
+</tbody></table>
+<p><img src="theme/lens.gif" height="16" width="15"> <strong>Virtual functions:
+  From static to dynamic C++ &nbsp;虚拟函数:从静态到动态的C++</strong></p>
<p>Rules straddle the border between static and dynamic C++. In effect, a rule transforms compile-time polymorphism (using templates) into run-time polymorphism (using virtual functions). This is necessary due to C++'s inability to automatically declare a variable of a type deduced from an arbitrarily complex expression in the right-hand side (rhs) of an assignment. Basically, we want to do something
-  like:</p>
-<pre><code><font color="#000000"> <span class=identifier>T </span><span class=identifier>rule </span><span class=special>= </span><span class=identifier>an_arbitrarily_complex_expression</span><span class=special>;</span></font></code></pre>
+  like:<br>规
+则跨越了静态与动态C++的边界。实际上,规则将编译期的多态(使用模板实现)转换为 运行期的多态(使用虚拟函数实现)。这是必要的,因为C++无法自动 +声明由一个赋值操作的右操作数(rhs)中某个任意复杂的表达式所推导出来的某种类型 的一个变量。基本上,我们想做的事情就象:</p> +<pre><code><font color="#000000"> <span class="identifier">T </span><span class="identifier">rule </span><span class="special">= </span><span class="identifier">an_arbitrarily_complex_expression</span><span class="special">;</span></font></code></pre> <p>without having to know or care about the resulting type of the right-hand side (rhs) of the assignment expression. Apart from this, we also need a facility
-  to forward declare an unknown type:</p>
-<pre><code><font color="#000000"><span class=special> </span><span class=identifier>T </span><span class=identifier>rule</span><span class=special>;
-    </span><span class=special>...
- </span><span class=identifier>rule </span><span class=special>= </span><span class=identifier>a </span><span class=special>| </span><span class=identifier>b</span><span class=special>;</span></font></code></pre> + to forward declare an unknown type:<br>而不必知道或关心赋值表达式右侧 (rhs)的结果类型。此外,我们还需要一种方法来前向声明一个未知的类型:</p> +<pre><code><font color="#000000"><span class="special"> </span><span class="identifier">T </span><span class="identifier">rule</span><span class="special">;<br> </span><span class="special">...<br> </span><span class="identifier">rule </span><span class="special">= </span><span class="identifier">a </span><span class="special">| </span><span class="identifier">b</span><span class="special">;</span></font></code></pre> <p>These limitations lead us to this implementation of rules. This comes at the expense of the overhead of a virtual function call, once through each invocation
-  of a rule.</p>
-<p><img src="theme/lens.gif" width="15" height="16"> <strong>Multiple declaration + of a rule.<br>这些限制使我们有了这种规则的实现。其代价是规则的每次调用都 有一次虚拟函数调用的开销。</p> +<p><img src="theme/lens.gif" height="16" width="15"> <strong>Multiple declaration 多次声明
   </strong> </p>
<p>Some BNF variants allow multiple declarations of a <tt>rule</tt>. The declarations
-  are taken as alternatives. Example:</p>
-<pre>
- <span class=identifier><code>r </code></span><code><span class=special>= </span><span class=identifier>a</span><span class=special>; </span><span class=identifier> - r </span><span class=special>= </span><span class=identifier>b</span><span class=special>;</span></code></pre>
-<p> is equivalent to: </p>
-<pre>
- <span class=identifier><code>r </code></span><code><span class=special>= </span><span class=identifier>a </span><span class=special>| </span><span class=identifier>b</span><span class=special>;</span></code></pre> + are taken as alternatives. Example:<br>有些BNF变体允许一个 <tt>rule</tt> 的多次声明。这些声明的结果是多选。例如:</p> +<pre> <span class="identifier"><code>r </code></span><code><span class="special">= </span><span class="identifier">a</span><span class="special">; </span><span class="identifier"> + r </span><span class="special">= </span><span class="identifier">b</span><span class="special">;</span></code></pre>
+<p> is equivalent to:<br>相当于: </p>
+<pre> <span class="identifier"><code>r </code></span><code><span class="special">= </span><span class="identifier">a </span><span class="special">| </span><span class="identifier">b</span><span class="special">;</span></code></pre> <p>Spirit v1.3 allowed this behavior. However, the current version of Spirit <b>no longer</b> allows this because experience shows that this behavior leads to unwanted gotchas (for instance, it does not allow rules to be held in containers). In the current release of Spirit, a second assignment to a rule will simply redefine it. The old definition is destructed. This follows more closely C++ - semantics and is more in line with what the user expects the rule to behave.</p> -<p><img src="theme/lens.gif" width="15" height="16"> <b>Sequencing Syntax</b>
-  <br>
+ semantics and is more in line with what the user expects the rule to behave.<br>Spirit v1.3 允许此种行为。但是,当前版本的Spirit<b>不再</b>允许此 种行为,因为经验显示,该行为会导致不必要的陷阱(例如,它不允许将规则保存于容 器之中)。在当前的Spirit版本中,对规则的第二次赋值只会重新定义它。旧的定义被 析构。这更接近于C++的语义,并与用户所期望的规则行为更为一致。</p> +<p><img src="theme/lens.gif" height="16" width="15"> <b>Sequencing Syntax 表示顺序的语法</b><br>
   <br>
The comma operator as in a, b seems to be a better candidate, syntax-wise. But then the problem is with its precedence. It has the lowest precedence in C/C++,
-  which makes it virtually useless. <br>
+ which makes it virtually useless.&nbsp;<br>逗号操作符如 a, b 似乎是一种更 好的选择,语法更明晰。但问题是它的优先级。在C/C++中它的优先级最低,这使得它 变得毫无用处。<br>
   <br>
- Bjarne Stroustrup, in his article <a href="references.html#generalized_overloading">&quot;Generalizing - Overloading for C++2000&quot;</a> talks about overloading whitespace. Such a + Bjarne Stroustrup, in his article <a href="references.html#generalized_overloading">"Generalizing
+  Overloading for C++2000"</a> talks about overloading whitespace. Such a
feature would allow juxtapositioning of parser objects exactly as we do in (E)BNF (e.g. a b | c instead of a &gt;&gt; b | c). Unfortunately, the article was dated
-  April 1, 1998. Oh well.</p>
-<p><img src="theme/lens.gif" width="15" height="16"> <b>Forward iterators</b><br> + April 1, 1998. Oh well.<br>Bjarne Stroustrup在它的文章 <a href="references.html#generalized_overloading">"Generalizing + Overloading for C++2000"</a> 中讨论了重载的空白。这种特性将允许分析器对象 的juxtapositioning正如我们在(E)BNF + 所做的一样(如以 a b | c 替代 a &gt;&gt; b | c)。不幸的是,文章的日期是 1998年4月1日。哦。</p> +<p><img src="theme/lens.gif" height="16" width="15"> <b>Forward iterators 前向迭代器</b><br>
   <br>
In general, the scanner expects at least a standard conforming forward iterator. Forward iterators are needed for backtracking where the iterator needs to be saved and restored later. Generally speaking, Spirit is a backtracking parser. The implication of this is that at some point, the iterator position will have to be saved to allow the parser to backtrack to a previous point. Thus, for - backtracking to work, the framework requires at least a forward iterator.<br> + backtracking to work, the framework requires at least a forward iterator.<br>一 +般来说,扫描器至少需要一个符合标准的前向迭代器。前向迭代器是回溯所需的,因 为迭代器需要被保存且稍后恢复。通常来说,Spirit是一个回溯分析器。 +其含义是,在某些时候,迭代器的位置必须被保存以允许分析器回溯至以前的点。因 此,为了可以回溯,本框架至少要求一个前向迭代器。<br>
   <br>
Some parsers might require more specialized iterators (bi-directional or even random access). Perhaps in the future, deterministic parsers when added to the framework, will perform no backtracking and will need just a single token lookahead,
-  hence will require input iterators only.</p>
-<p><img src="theme/lens.gif" width="15" height="16"><b> Why are subrules important?</b><br> + hence will require input iterators only.<br>有些分析器可能要求更为特殊的 迭代器(双向的甚至是随机访问的)。也许在将来,确定性的分析器被增加到本框架中 时,将不再执行回溯,只需要前瞻一个记号,这时只需要输入迭代器即可。</p> +<p><img src="theme/lens.gif" height="16" width="15"><b> Why are subrules important? 为什么子规则是重要的?</b><br>
   <br>
Subrules open up the oportunity to do aggressive meta programming as well because they do not rely on virtual functions. The virtual function is the meta-programmer's
@@ -90,8 +89,10 @@
call, it is also an opaque wall where no metaprogram can get past. It kills all meta-information beyond the virtual function call. Worse, the virtual function cannot be templated. Which means that its arguments have to be tied to a actual
-  types. Many problems stem from this limitation. <br>
-  <br>
+  types. Many problems stem from this limitation.&nbsp;<br>子
+规则提供了元编程的机会,因为它们不依赖于虚拟函数。虚拟函数是元编程者的地 狱。它不仅因为虚拟函数的间接调用降低了程序的速度,它还是一堵不透明的墙, +元编程无法穿过它。它在虚拟函数调用之前去掉了所有元信息。更糟的是,虚拟函数 不能被模板化。这意味着它的参数必须绑定至实际的类型。许多问题正是源于这
+个限制。<br></p><p>
While Spirit is a currently classified as a non-deterministic recursive-descent parser, Doug Gregor first noted that other parsing techniques apart from top-down recursive descent may be applied. For instance, apart from non-deterministic
@@ -99,29 +100,35 @@
using the same expression template front end. Spirit rules use virtual functions to encode the RHS parser expression in an opaque abstract parser type. While it serves its purpose well, the rule's virtual functions are the stumbling blocks - to more advanced metaprogramming. Subrules are free from virtual functions.</p> -<p><img src="theme/lens.gif" width="15" height="16"><b> <a name="exhaustive_rd"></a>Exhaustive
-  backtracking and greedy RD</b></p>
+ to more advanced metaprogramming. Subrules are free from virtual functions.<br>虽
+然目前Spirit被分类为非确定性的递归下降分析器,但Doug
+Gregor首先注意到,除了自顶而下的递归下降法以外的其它分析技术也是可以适用 的。例如,除了非确定性的递归下降法,确定性的 LL(1) 和
+LR(1)
+理论上也可以被实现为使用相同的表达式模板前端。Spirit的规则使用了虚拟函数来 将RHS分析器表达式编码为一个不透明的抽象分析器类型。虽然它很好 +地达到其目的,但是规则所用的虚拟函数是进一步使用元编程的绊脚石。子规则则不 受虚拟函数的限制。</p> +<p><img src="theme/lens.gif" height="16" width="15"><b> <a name="exhaustive_rd"></a>Exhaustive
+  backtracking and greedy RD 穷举回溯和贪心RD</b></p>
<p>Spirit doesn't do exhaustive backtracking like regular expressions are expected
-  to. For example:</p>
+ to. For example:<br>Spirit并不象正则表达式所期望的那样进行穷举回溯。例 如:</p> <pre> <span class="special">*</span>chlit_p<span class="special">(</span><span class="quotes">'a'</span><span class="special">) &gt;&gt;</span> chlit_p<span class="special">(</span><span class="quotes">'a'</span><span class="special">);</span></pre> <p>will always fail to match because Spirit's Kleene star does not back off when
-  the rest of the rule fails to match. </p>
+ the rest of the rule fails to match.<br>总是匹配失败,因为当规则的其余部 分匹配失败时,Spirit的克林星不会回退。 </p> <p>Actually, there's a solution to this greedy RD problem. Such a scheme is discussed
-  in section 6.6.2 of <a
-href="http://www.cs.vu.nl/%7Edick/PTAPG.html";>Parsing Techniques: A Practical + in section 6.6.2 of <a href="http://www.cs.vu.nl/%7Edick/PTAPG.html";>Parsing Techniques: A Practical Guide</a>. The trick involves passing a <em>tail</em> parser (in addition to the scanner) to each parser. The start parser will then simply be: <tt>start
-  &gt;&gt; end_p;</tt> (end_p is the start's tail). </p>
+ &gt;&gt; end_p;</tt> (end_p is the start's tail).<br>实际上,这个贪心RD的 问题有一个解决方法。该机制在 <a href="http://www.cs.vu.nl/%7Edick/PTAPG.html";>Parsing Techniques: A Practical + Guide</a> 的第6.6.2节中讨论。该诀窍包含了传递一个 <em>tail</em> 分析器(除 了扫描器以外)给每一个分析器。然后起始分析器只需写成:<tt>start
+  &gt;&gt; end_p;</tt> (end_p 是 start 的 tail)。 </p>
<p>Spirit is greedy --using straight forward, naive RD. It is certainly possible to implement the fully backtracking scheme presented above, but there will be also certainly be a performance hit. The scheme will always try to match all possible parser paths (full parser hierarchy traversal) until it reaches a point
-  of certainty, that the whole thing matches or fails to match. </p>
-<table border="0" width="80%" align="center">
-  <tr>
- <td class="note_box"><p><img src="theme/note.gif" width="16" height="16"><b>Backtracking
-        and Greedy RD </b><br>
+ of certainty, that the whole thing matches or fails to match.<br>Spirit是 贪心的--使用简单、自然的RD。当然,它可以实现以上所说的全回溯机制,但是显然这 也是一个性能上的挑战。该机制总是尝试匹配所有可能的分析器路径(完全的分析器层 次遍历),直至到达某个可以确定完全匹配或匹配失败的点。 </p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><p><img src="theme/note.gif" height="16" width="16"><b>Backtracking
+        and Greedy RD 回溯与贪心RD </b><br>
         <br>
Spirit is quite consistent and intuitive about when it backtracks and to where, although it may not be obvious to those coming from different
@@ -130,33 +137,36 @@
This means that Spirit is inherently greedy. Spirit will only backtrack when a (sub)parser fails to match the input, and it will always backtrack to the next choice point upward (not backward) in the parser structure. - In other words abb|ab will match &quot;ab&quot;, as will a(bb|b), but
+        In other words abb|ab will match "ab", as will a(bb|b), but
(ab|a)b won't because the (ab|a) subparser will always match the 'b' after
-        the 'a' if it is available.</p>
+        the 'a' if it is available.</p><p>Spirit
+对于何时回溯以及回溯至何处是相当连贯和直观的,虽然对于来自不同的背景它可能 不是很明显。通常,任何(子)分析器,给定相同的输入,总是匹配相同的部分 +输入(或者根本就匹配失败)。这意味着Spirit本身就是贪心的。Spirit仅当一个(子 )分析器匹配输入失败时才进行回溯,而且它总是回溯至分析器 +结构中向上的(不是向后)下一个选择点。换句话说,abb|ab 将匹配 "ab",a(bb|b) 也一样,但 (ab|a)b
+则非如此,因为子分析器 (ab|a) 只要可能就总是在 'a' 之后匹配一个 'b'。</p>
       <p>--Rainer Deyke</p>
       </td>
   </tr>
-</table>
-<p>There's a strong preference on &quot;simplicity with all the knobs when you - need them&quot; approach, right now. On the other hand, the flexibility of Spirit
+</tbody></table>
+<p>There's a strong preference on "simplicity with all the knobs when you
+ need them" approach, right now. On the other hand, the flexibility of Spirit makes it possible to have different optional schemes available. It might be possible to implement an exhaustive backtracking RD scheme as an optional feature
-  in the future. </p>
+ in the future.<br>对于"需要时就使用所有旋钮"这一方法,现在有一种强烈的偏 好。另一方面,Spirit的灵活性令它可以有不同的可选机制。将来它也许可以实现一个 穷举回溯的RD机制作为可选的特性。 </p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="faq.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="acknowledgments.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/references.html      Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/references.html      Mon Oct 12 20:27:43 2009
@@ -1,188 +1,176 @@
-<html>
-<head>
-<title>References</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>References</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
     <td width="85%">
- <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>References</b></font> + <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>References 参考资料</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="acknowledgments.html"><img src="theme/l_arr.gif" border="0"></a></td> - <td width="30"><img src="theme/r_arr_disabled.gif" width="20" height="19"></td> + <td width="30"><img src="theme/r_arr_disabled.gif" height="19" width="20"></td>
   </tr>
-</table>
+</tbody></table>
 <br>
-<table width="90%" border="0" align="center">
-  <tr>
-    <td width="36" class="table_cells"> 1.</td>
- <td width="236" class="table_cells"> <a name="expression_templates"></a>Todd
+<table align="center" border="0" width="90%">
+  <tbody><tr>
+    <td class="table_cells" width="36"> 1.</td>
+ <td class="table_cells" width="236"> <a name="expression_templates"></a>Todd
       Veldhuizen</td>
-    <td width="520" class="table_cells"> "<a
-href="http://www.extreme.indiana.edu/%7Etveldhui/papers/Expression-Templates/exprtmpl.html";>Expression
+ <td class="table_cells" width="520"> "<a href="http://www.extreme.indiana.edu/%7Etveldhui/papers/Expression-Templates/exprtmpl.html";>Expression
       Templates</a>". <br>
       C++ Report, June 1995.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells"> 2.</td>
- <td width="236" class="table_cells"> <a name="bnf"></a>Peter Naur (ed.)</td> - <td width="520" class="table_cells"> "<a href="http://www.masswerk.at/algol60/report.htm";>Report
+    <td class="table_cells" width="36"> 2.</td>
+ <td class="table_cells" width="236"> <a name="bnf"></a>Peter Naur (ed.)</td> + <td class="table_cells" width="520"> "<a href="http://www.masswerk.at/algol60/report.htm";>Report
       on the Algorithmic Language ALGOL 60</a>". <br>
       CACM, May 1960.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells"> 3.</td>
-    <td width="236" class="table_cells"> ISO/IEC</td>
-    <td width="520" class="table_cells"> "<a
-href="http://www.cl.cam.ac.uk/%7Emgk25/iso-14977.pdf";>ISO-EBNF</a>", <br>
+    <td class="table_cells" width="36"> 3.</td>
+    <td class="table_cells" width="236"> ISO/IEC</td>
+ <td class="table_cells" width="520"> "<a href="http://www.cl.cam.ac.uk/%7Emgk25/iso-14977.pdf";>ISO-EBNF</a>", <br>
       ISO/IEC 14977: 1996(E).</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells"> 4.</td>
- <td width="236" class="table_cells"> <a name="intersections"></a>Richard J.
+    <td class="table_cells" width="36"> 4.</td>
+ <td class="table_cells" width="236"> <a name="intersections"></a>Richard J.
       Botting, Ph.D. </td>
-    <td width="520" class="table_cells"> "<a
-href="http://www.csci.csusb.edu/dick/maths/intro_ebnf.html";>XBNF</a>" (citing + <td class="table_cells" width="520"> "<a href="http://www.csci.csusb.edu/dick/maths/intro_ebnf.html";>XBNF</a>" (citing
       Leu-Weiner, 1973). <br>
       California State University, San Bernardino, 1998. </td>
   </tr>
   <tr>
-    <td width="36" class="table_cells"> 5.</td>
- <td width="236" class="table_cells"> <a name="curious_recurring"></a>James
+    <td class="table_cells" width="36"> 5.</td>
+ <td class="table_cells" width="236"> <a name="curious_recurring"></a>James
       Coplien. </td>
- <td width="520" class="table_cells"> "<b>Curiously Recurring Template Pattern</b>". + <td class="table_cells" width="520"> "<b>Curiously Recurring Template Pattern</b>".
       <br>
       C++ Report, Feb. 1995.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells"> 6.</td>
- <td width="236" class="table_cells"> <a name="generic_patterns"></a>Thierry
-      G&eacute;raud and <br>
+    <td class="table_cells" width="36"> 6.</td>
+ <td class="table_cells" width="236"> <a name="generic_patterns"></a>Thierry
+      Géraud and <br>
       Alexandre Duret-Lutz</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.coldewey.com/europlop2000/papers/geraud%2Bduret.zip";>Generic
+ <td class="table_cells" width="520"> <a href="http://www.coldewey.com/europlop2000/papers/geraud%2Bduret.zip";>Generic
       Programming Redesign of Patterns</a><br>
Proceedings of the 5th European Conference on Pattern Languages of Programs
       <br>
       (EuroPLoP'2000) Irsee, Germany, July 2000. </td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">7.</td>
-    <td width="236" class="table_cells">Geoffrey Furnish</td>
- <td width="520" height="53" class="table_cells"><a href="http://www.adtmag.com/joop/crarticle.asp?ID=627";>&quot;Disambiguated
-      Glommable Expression Templates Reintroduced&quot;</a><br>
+    <td class="table_cells" width="36">7.</td>
+    <td class="table_cells" width="236">Geoffrey Furnish</td>
+ <td class="table_cells" height="53" width="520"><a href="http://www.adtmag.com/joop/crarticle.asp?ID=627";>"Disambiguated
+      Glommable Expression Templates Reintroduced"</a><br>
       C++ Report, May 2000</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">8.</td>
-    <td width="236" height="53" class="table_cells"> Erich Gamma, <br>
+    <td class="table_cells" width="36">8.</td>
+    <td class="table_cells" height="53" width="236"> Erich Gamma, <br>
       Richard Helm, <br>
       Ralph Jhonson, <br>
       and John Vlissides</td>
- <td width="520" height="53" class="table_cells"> <b>Design Patterns, Elements + <td class="table_cells" height="53" width="520"> <b>Design Patterns, Elements
       of Reusable Object-Oriented Software</b>. <br>
       Addison-Wesley, 1995.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">9. </td>
-    <td width="236" class="table_cells">Alfred V. Aho<br>
+    <td class="table_cells" width="36">9. </td>
+    <td class="table_cells" width="236">Alfred V. Aho<br>
       Revi Sethi<br>
       Feffrey D. Ulman</td>
- <td width="520" class="table_cells"><b>Compilers, Principles, Techniques and + <td class="table_cells" width="520"><b>Compilers, Principles, Techniques and
       Tools</b><br>
       Addison-Wesley, June 1987. </td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">10. </td>
-    <td width="236" class="table_cells"> Dick Grune and <br>
+    <td class="table_cells" width="36">10. </td>
+    <td class="table_cells" width="236"> Dick Grune and <br>
       Ceriel Jacobs</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.cs.vu.nl/%7Edick/PTAPG.html";>Parsing Techniques: A Practical + <td class="table_cells" width="520"> <a href="http://www.cs.vu.nl/%7Edick/PTAPG.html";>Parsing Techniques: A Practical
       Guide</a>. <br>
Ellis Horwood Ltd.: West Sussex, England, 1990. (electronic copy, 1998).</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">11. </td>
-    <td width="236" class="table_cells"> T. J. Parr, H. G. Dietz, and<br>
+    <td class="table_cells" width="36">11. </td>
+    <td class="table_cells" width="236"> T. J. Parr, H. G. Dietz, and<br>
       W. E. Cohen</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.antlr.org/papers/pcctsbk.pdf";>PCCTS Reference Manual (Version + <td class="table_cells" width="520"> <a href="http://www.antlr.org/papers/pcctsbk.pdf";>PCCTS Reference Manual (Version
       1.00)</a>. <br>
School of Electrical Engineering, Purdue University, West Lafayette, August
       1991.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">12. </td>
- <td width="236" class="table_cells"> Adrian Johnstone and Elizabeth Scott.</td>
-    <td width="520" class="table_cells"> <a
-href="ftp://ftp.cs.rhul.ac.uk/pub/rdp";>RDP, A Recursive Descent Compiler Compiler</a>.
+    <td class="table_cells" width="36">12. </td>
+ <td class="table_cells" width="236"> Adrian Johnstone and Elizabeth Scott.</td> + <td class="table_cells" width="520"> <a href="ftp://ftp.cs.rhul.ac.uk/pub/rdp";>RDP, A Recursive Descent Compiler Compiler</a>.
       <br>
Technical Report CSD TR 97 25, Dept. of Computer Science, Egham, Surrey,
       England, Dec. 20, 1997. </td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">13. </td>
- <td width="236" class="table_cells"> <a name="back_tracking_parsers"></a>Adrian
+    <td class="table_cells" width="36">13. </td>
+ <td class="table_cells" width="236"> <a name="back_tracking_parsers"></a>Adrian
       Johnstone</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.cs.rhul.ac.uk/research/languages/projects/lookahead_backtrack.shtml";>Languages
+ <td class="table_cells" width="520"> <a href="http://www.cs.rhul.ac.uk/research/languages/projects/lookahead_backtrack.shtml";>Languages
       and Architectures, <br>
Parser generators with backtrack or extended lookahead capability</a><br> Department of Computer Science, Royal Holloway, University of London, Egham,
       Surrey, England</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">14. </td>
- <td width="236" class="table_cells"> <a name="damian_conway"></a>Damian Conway</td> - <td width="520" class="table_cells"><a href="http://www.csse.monash.edu.au/%7Edamian/papers/#Embedded_Input_Parsing_for_C";>Parsing
+    <td class="table_cells" width="36">14. </td>
+ <td class="table_cells" width="236"> <a name="damian_conway"></a>Damian Conway</td> + <td class="table_cells" width="520"><a href="http://www.csse.monash.edu.au/%7Edamian/papers/#Embedded_Input_Parsing_for_C";>Parsing
       with C++ Classes.</a><br>
       ACM SIGPLAN Notices, 29:1, 1994.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">15. </td>
-    <td width="236" class="table_cells"> Joel de Guzman</td>
- <td width="520" class="table_cells"><a href="http://spirit.sourceforge.net/index.php?doc=docs/v1_3/index.html";>&quot;Spirit
-      Version 1.3&quot;</a>. <br>
+    <td class="table_cells" width="36">15. </td>
+    <td class="table_cells" width="236"> Joel de Guzman</td>
+ <td class="table_cells" width="520"><a href="http://spirit.sourceforge.net/index.php?doc=docs/v1_3/index.html";>"Spirit
+      Version 1.3"</a>. <br>
       http://spirit.sourceforge.net/, November 2001.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">16. </td>
- <td width="236" class="table_cells"> <a name="combinators"></a>S. Doaitse
+    <td class="table_cells" width="36">16. </td>
+ <td class="table_cells" width="236"> <a name="combinators"></a>S. Doaitse
       Swierstra and <br>
       Luc Duponcheel</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.cs.uu.nl/groups/ST/Publications/AFP2.pdf";>Deterministic, Error-Correcting + <td class="table_cells" width="520"> <a href="http://www.cs.uu.nl/groups/ST/Publications/AFP2.pdf";>Deterministic, Error-Correcting
       Combinator Parsers </a><br>
Dept. of Computer Science, Utrecht University P.O.Box 80.089, 3508 TB Utrecht,
       The Netherland</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">17.</td>
- <td width="236" class="table_cells"> <a name="generalized_overloading"></a>Bjarne
+    <td class="table_cells" width="36">17.</td>
+ <td class="table_cells" width="236"> <a name="generalized_overloading"></a>Bjarne
       Stroustrup</td>
-    <td width="520" class="table_cells"> <a
-href="http://www.research.att.com/%7Ebs/whitespace98.pdf";>Generalizing Overloading + <td class="table_cells" width="520"> <a href="http://www.research.att.com/%7Ebs/whitespace98.pdf";>Generalizing Overloading
       for C++2000</a><br>
       Overload, Issue 25. April 1, 1998.</td>
   </tr>
   <tr>
-    <td width="36" class="table_cells">18.</td>
- <td width="236" class="table_cells"><a name="regex_boost_doc"></a>Dr. John
+    <td class="table_cells" width="36">18.</td>
+ <td class="table_cells" width="236"><a name="regex_boost_doc"></a>Dr. John
       Maddock</td>
- <td width="520" class="table_cells"><a href="http://www.boost.org/libs/regex/index.html";>Regex++ + <td class="table_cells" width="520"><a href="http://www.boost.org/libs/regex/index.html";>Regex++
       Documentation</a><br>
       http://www.boost.org/libs/regex/index.htm </td>
   </tr>
@@ -217,24 +205,23 @@
<td class="table_cells"> <a href="ftp://ftp.cs.indiana.edu/pub/techreports/TR542.pdf";>Techniques
       for Scientic C++.</a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="acknowledgments.html"><img src="theme/l_arr.gif" border="0"></a></td> - <td width="30"><img src="theme/r_arr_disabled.gif" width="20" height="19"></td> + <td width="30"><img src="theme/r_arr_disabled.gif" height="19" width="20"></td>
    </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p>&nbsp;</p>
 <p>&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/style_guide.html     Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/style_guide.html     Mon Oct 12 20:27:43 2009
@@ -1,124 +1,95 @@
-<html>
-<head>
-<title>Style Guide</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Style Guide</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Style
-      Guide </b></font></td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Style
+      Guide 风格指南 </b></font></td>
+ <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="portability.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p> At some point, especially when there are lots of semantic actions attached to various points, the grammar tends to be quite difficult to follow. In order to keep an easy-to-read, consistent en aesthetically pleasing look to the Spirit
-  code, the following coding styleguide is advised. </p>
+ code, the following coding styleguide is advised.<br>有些时候,尤其是当有 大量语义动作附着于各个地方时,语法会变得非常难以理解。为了保持易读性,风格一 致的Spirit代码会更美观,以下是我们建议的代码风格。 </p> <p>This coding style is adapted and extended from the ANTLR/PCCTS style (Terrence Parr) and <a href="http://groups.yahoo.com/group/boost/files/coding_guidelines.html";>Boost coding guidelines</a> (David Abrahams and Nathan Myers) and is the combined
-  work of Joel de Guzman, Chris Uzdavinis and Hartmut Kaiser.</p>
+ work of Joel de Guzman, Chris Uzdavinis and Hartmut Kaiser.<br>这些代码风 格是从 ANTLR/PCCTS 风格(Terrence + Parr)和 <a href="http://groups.yahoo.com/group/boost/files/coding_guidelines.html";>Boost + 编码指导方针</a>(David Abrahams 和 Nathan Myers)修改和扩展而来的,并结合 了 Joel de Guzman, Chris Uzdavinis 和 Hartmut Kaiser 的工作。</p>
 <ul>
- <li> Rule names use std C++ (Boost) convention. The rule name may be very long.</li> + <li> Rule names use std C++ (Boost) convention. The rule name may be very long.<br>规则名使用 std C++ (Boost) 命名约定。规则名可能非常长。</li> <li>The '=' is neatly indented 4 spaces below. Like Boost, use spaces instead
-    of tabs. </li>
+ of tabs.<br>'=' 如下缩入4个空格。和Boost一样,用空格符替代制表符。 </li> <li>Breaking the operands into separate lines puts the semantic actions neatly
-    to the right. </li>
-  <li>Semicolon at the last line terminates the rule. </li>
+ to the right.<br>将操作数分开到不同的行,将相应的语义动作放在右边。 </li> + <li>Semicolon at the last line terminates the rule.<br>最后一行用分号结束 该规则。 </li> <li>The adjacent parts of a sequence should be indented accordingly to have
-    all, what belongs to one level, at one indentation level.</li>
+ all, what belongs to one level, at one indentation level.<br>一个序列的 相邻部分应根据层级缩入,属于同一级的采用相同的缩入。</li>
 </ul>
-<pre><span class=identifier>    program
- </span><span class=special>= </span><span class=identifier>program_heading </span><span class=special>[</span><span class=identifier>heading_action</span><span class=special>] - </span><span class=identifier> </span><span class=special> &gt;&gt; </span><span class=identifier>block </span><span class=special>[</span><span class=identifier>block_action</span><span class=special>] - </span><span class=identifier> </span><span class=special> &gt;&gt; </span><span class=literal>'.' - </span><span class=identifier> </span><span class=special>| </span><span class=identifier>another_sequence - </span><span class=special>&gt;&gt; </span><span class=identifier>etc - </span><span class=identifier> </span><span class=special>;</span></pre> +<pre><span class="identifier"> program<br> </span><span class="special">= </span><span class="identifier">program_heading </span><span class="special">[</span><span class="identifier">heading_action</span><span class="special">]<br> </span><span class="identifier"> </span><span class="special"> &gt;&gt; </span><span class="identifier">block </span><span class="special">[</span><span class="identifier">block_action</span><span class="special">]<br> </span><span class="identifier"> </span><span class="special"> &gt;&gt; </span><span class="literal">'.'<br> </span><span class="identifier"> </span><span class="special">| </span><span class="identifier">another_sequence<br> </span><span class="special">&gt;&gt; </span><span class="identifier">etc<br> </span><span class="identifier"> </span><span class="special">;</span></pre>
 <ul>
- <li>Prefer literals in the grammar instead of identifiers. e.g. <tt>&quot;program&quot;</tt> + <li>Prefer literals in the grammar instead of identifiers. e.g. <tt>"program"</tt> instead of <tt>PROGRAM</tt>, <tt>'&gt;='</tt> instead of <tt>GTE</tt> and <tt>'.' </tt>instead of <tt>DOT</tt>. This makes it much easier to read. If this isn't possible (for instance where the used tokens must be identified
-    through integers) capitalized identifiers should be used instead. </li>
+ through integers) capitalized identifiers should be used instead.<br>在 语法中优先使用字面量而不是标识符,如,用 <tt>"program"</tt> 替代 <tt>PROGRAM</tt>, 用 <tt>'&gt;='</tt> 替代 <tt>GTE</tt> 以及用 + <tt>'.' </tt>替代 <tt>DOT</tt>。这样可以令语法更易读。如果不可能这么做 (如被用的记号必须通过整数来标识),则将标识符大写。 </li> <li> Breaking the operands may not be needed for short expressions. e.g. <tt>*(',' - &gt;&gt; file_identifier)</tt> as long as the line does not exceed 80 characters. + &gt;&gt; file_identifier)</tt> as long as the line does not exceed 80 characters.<br>对于较短的表达式,如 <tt>*(',' + &gt;&gt; file_identifier)</tt>,只要该行不超出80个字符,就不需要将操作 数分拆。
   </li>
<li> If a sequence fits on one line, put spaces inside the parentheses to clearly
-    separate them from the rules. </li>
+ separate them from the rules.<br>如果一个序列可放入一行,则将空格放在括 号中将它们与规则明确分隔开。 </li>
 </ul>
-<pre>    <span class=identifier>program_heading
- </span><span class=special>= </span><span class=identifier>as_lower_d</span><span class=special>[</span><span class=string>&quot;program&quot;</span><span class=special>]
-            &gt;&gt; </span><span class=identifier>identifier
- </span><span class=special>&gt;&gt; </span><span class=literal>'(' - </span><span class=special>&gt;&gt; </span><span class=identifier>file_identifier - </span><span class=special>&gt;&gt; *( </span><span class=literal>',' </span><span class=special>&gt;&gt; </span><span class=identifier>file_identifier </span><span class=special>)
-            &gt;&gt; </span><span class=literal>')'
- </span><span class=special>&gt;&gt; </span><span class=literal>';'
-        </span><span class=special>;</span></pre>
+<pre> <span class="identifier">program_heading<br> </span><span class="special">= </span><span class="identifier">as_lower_d</span><span class="special">[</span><span class="string">"program"</span><span class="special">]<br> &gt;&gt; </span><span class="identifier">identifier<br> </span><span class="special">&gt;&gt; </span><span class="literal">'('<br> </span><span class="special">&gt;&gt; </span><span class="identifier">file_identifier<br> </span><span class="special">&gt;&gt; *( </span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">file_identifier </span><span class="special">)<br> &gt;&gt; </span><span class="literal">')'<br> </span><span class="special">&gt;&gt; </span><span class="literal">';'<br> </span><span class="special">;</span></pre>
 <ul>
<li> Nesting directives: If a rule does not fit on one line (80 characters)
-    it should be continued on the next line intended by one level. </li>
+ it should be continued on the next line intended by one level.<br>嵌套 指示符:如果一个规则不适合放在一行中(80个字符),则应在下一行缩入一级继续。 </li> <li>The brackets of directives, semantic expressions (using Phoenix or LL lambda
-    expressions) or parsers should be placed as follows. </li>
+ expressions) or parsers should be placed as follows.<br>指示符、语义表 达式(使用 Phoenix 或 LL lambda 表达式)或分析器的括号应如下放置。 </li>
 </ul>
-<pre>    <span class=identifier>identifier
-        </span><span class=special>=   </span><span class=identifier>nocase
-            </span><span class=special>[
-                </span><span class=identifier>lexeme
-                </span><span class=special>[
- </span><span class=identifier>alpha </span><span class=special>&gt;&gt; *(</span><span class=identifier>alnum </span><span class=special>| </span><span class=literal>'_'</span><span class=special>) [</span><span class=identifier>id_action</span><span class=special>]
-                ]
-            ]
-        ;</span></pre>
+<pre> <span class="identifier">identifier<br> </span><span class="special">= </span><span class="identifier">nocase<br> </span><span class="special">[<br> </span><span class="identifier">lexeme<br> </span><span class="special">[<br> </span><span class="identifier">alpha </span><span class="special">&gt;&gt; *(</span><span class="identifier">alnum </span><span class="special">| </span><span class="literal">'_'</span><span class="special">) [</span><span class="identifier">id_action</span><span class="special">]<br> ]<br> ]<br> ;</span></pre>
 <ul>
-  <li> Nesting unary operators (e.g.Kleene star) </li>
+ <li> Nesting unary operators (e.g.Kleene star)<br>嵌套的单参操作符(如克林 星) </li> <li>Unary rule operators (Kleene star, <tt>'!'</tt>, <tt>'+'</tt> etc.) should be moved out one space before the corresponding indentation level, if this rule has a body or a sequence after it, which does not fit on on line. This makes the formatting more consistent and moves the rule 'body' at the same - indentation level as the rule itself, highlighting the unary operator.</li> + indentation level as the rule itself, highlighting the unary operator.<br>单参规则操作符(克林星, <tt>'!'</tt>, <tt>'+'</tt> 等等)应比相应 的缩入级前移一格,如果该规则之后有一个规则体或序列且不能在一行中写完。这样格 式更为统一且将规则体移至与规则本身相同的缩入级,突出了单参操作符。</li>
 </ul>
-<pre><span class=special>    </span><span class=identifier>block
- </span><span class=special>= *( </span><span class=identifier>label_declaration_part - </span><span class=special>| </span><span class=identifier>constant_definition_part - </span><span class=special>| </span><span class=identifier>type_definition_part - </span><span class=special>| </span><span class=identifier>variable_declaration_part - </span><span class=special>| </span><span class=identifier>procedure_and_function_declaration_part
-            </span><span class=special>)
-            &gt;&gt; </span><span class=identifier>statement_part
-        </span><span class=special>;</span></pre>
+<pre><span class="special"> </span><span class="identifier">block<br> </span><span class="special">= *( </span><span class="identifier">label_declaration_part<br> </span><span class="special">| </span><span class="identifier">constant_definition_part<br> </span><span class="special">| </span><span class="identifier">type_definition_part<br> </span><span class="special">| </span><span class="identifier">variable_declaration_part<br> </span><span class="special">| </span><span class="identifier">procedure_and_function_declaration_part<br> </span><span class="special">)<br> &gt;&gt; </span><span class="identifier">statement_part<br> </span><span class="special">;</span></pre>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="portability.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="techniques.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2001-2003 Joel de Guzman<br>
-  Copyright &copy; 2001-2002 Hartmut Kaiser<br>
-  Copyright &copy; 2001-2002 Chris Uzdavinis<br>
+<p class="copyright">Copyright © 2001-2003 Joel de Guzman<br>
+  Copyright © 2001-2002 Hartmut Kaiser<br>
+  Copyright © 2001-2002 Chris Uzdavinis<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/symbols.html Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/symbols.html Mon Oct 12 20:27:43 2009
@@ -1,35 +1,34 @@
-<html>
-<head>
-<title>Symbols</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Symbols</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
     <td width="85%">
- <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Symbols</b></font> + <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Symbols 符号表</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="distinct.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="trees.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
<p>This class symbols implements a symbol table. The symbol table holds a dictionary of symbols where each symbol is a sequence of CharTs (a <tt>char</tt>, <tt>wchar_t</tt>, <tt>int</tt>, enumeration etc.) . The template class, parameterized by the character type (CharT), can work efficiently with 8, 16, 32 and even 64 bit characters.
-  Mutable data of type T is associated with each symbol.<br>
+ Mutable data of type T is associated with each symbol.<br>这个类 symbols 实现了一个符号表。该符号表保存一个符号字典,其中每个符号是一个 CharTs (一个 <tt>char</tt>, <tt>wchar_t</tt>, + <tt>int</tt>, 或枚举值等等)的序列。这是一个模板类,按字符类型(CharT)参数 化,可以有效地工作于 8, 16, 32 甚至 64 位字符。可变数据类型 T 被关联到每个符 号。<br>
 </p>
<p>Traditionally, symbol table management is maintained seperately outside the BNF grammar through semantic actions. Contrary to standard practice, the Spirit
@@ -37,29 +36,25 @@
used anywhere in the EBNF grammar specification. It is an example of a dynamic parser. A dynamic parser is characterized by its ability to modify its behavior at run time. Initially, an empty symbols object matches nothing. At any time,
-  symbols may be added, thus, dynamically altering its behavior.</p>
+ symbols may be added, thus, dynamically altering its behavior.<br>传统 上,符号表管理是通过语义动作分离到BNF语法之外的。与标准的做法相反,Spirit的 符号表类 <tt>symbols</tt> 本身就是一个分析器。它的实例可以被用于EBNF语法规范 的任何地主。它是一个动态分析器的例子。动态分析器的特点是它能够修改其在运行期 的行为。起初,一个空的 symbols 对象不匹配任何东西。符合可以在任何时候被加 入,以动态地改变其行为。</p> <p>Each entry in a symbol table has an associated mutable data slot. In this regard, one can view the symbol table as an associative container (or map) of key-value
-  pairs where the keys are strings. </p>
+ pairs where the keys are strings.<br>符号表中的每一项都有一个相关联的可变 数据插槽。在这方面,你可以将符号表视为一个键-值对的关联容器(或映射),其键为 字符串。 </p> <p>The symbols class expects two template parameters (actually there is a third, see detail box). The first parameter <tt>T</tt> specifies the data type associated with each symbol (defaults to <tt>int</tt>) and the second parameter <tt>CharT</tt> - specifies the character type of the symbols (defaults to <tt>char</tt>). </p>
-<pre><span class=identifier>    </span><span class=keyword>template
-    </span><span class=special>&lt;
- </span><span class=keyword>typename </span><span class=identifier>T </span><span class=special>= </span><span class=keyword>int</span><span class=special>, - </span><span class=keyword>typename </span><span class=identifier>CharT </span><span class=special>= </span><span class=keyword>char</span><span class=special>, - </span><span class=keyword>typename </span><span class=identifier>SetT </span><span class=special>= </span><span class=identifier>impl</span><span class=special>::</span><span class=identifier>tst</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=identifier>CharT</span><span class=special>&gt;
-    </span><span class=special>&gt;
- </span><span class=keyword>class </span><span class=identifier>symbols</span><span class=special>;</span></pre>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"><img src="theme/lens.gif" width="15" height="16"> <b>Ternary
-      State Trees</b><br>
+ specifies the character type of the symbols (defaults to <tt>char</tt>).<br>symbols 类有两个模板参数(实际上还有第三个,请见详细说明 )。第一个参数 <tt>T</tt> 指定与每个符号相关联的数据类型(缺省为 <tt>int</tt>),而第二个参数 <tt>CharT</tt>
+  则指定符号的字符类型(缺省为 <tt>char</tt>)。 </p>
+<pre><span class="identifier"> </span><span class="keyword">template<br> </span><span class="special">&lt;<br> </span><span class="keyword">typename </span><span class="identifier">T </span><span class="special">= </span><span class="keyword">int</span><span class="special">,<br> </span><span class="keyword">typename </span><span class="identifier">CharT </span><span class="special">= </span><span class="keyword">char</span><span class="special">,<br> </span><span class="keyword">typename </span><span class="identifier">SetT </span><span class="special">= </span><span class="identifier">impl</span><span class="special">::</span><span class="identifier">tst</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">, </span><span class="identifier">CharT</span><span class="special">&gt;<br> </span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">symbols</span><span class="special">;</span></pre>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><img src="theme/lens.gif" height="16" width="15"> <b>Ternary
+      State Trees 三元状态树</b><br>
       <br>
The actual set implementation is supplied by the SetT template parameter (3rd template parameter of the symbols class) . By default, this uses the
-      tst class which is an implementation of the Ternary Search Tree. <br>
+ tst class which is an implementation of the Ternary Search Tree. <br>实际的集合实现由模板参数 SetT 提供(即 symbols 类的第3个模板参数)。缺省 地,它使用一个三元状态树
+      tst 类。<br>
       <br>
Ternary Search Trees are faster than hashing for many typical search problems especially when the search interface is iterator based. Searching for a
@@ -67,138 +62,109 @@
at most O(log n+k) character comparisons. TSTs are many times faster than hash tables for unsuccessful searches since mismatches are discovered earlier after examining only a few characters. Hash tables always examine an entire
-      key when searching.<br>
+      key when searching.<br>三
+元状态树在许多典型的搜索问题中要快于散列,特别是当搜索接口是基于迭代器的时 候。在一个带有 n 个字符串的三元状态树中搜索一个长度为 k
+的字符串,至多需要 O(log n+k) 次字符比较。对于不成功的搜索,TSTs
+要比散列表快出许多倍,因为失配的情况可以在只比较少量几个字符之后,就更早地 被察觉。散列表在搜索时则总是测试整个键值。<br>
       <br>
- For details see <a href="http://www.cs.princeton.edu/%7Ers/strings/";>http://www.cs.princeton.edu/~rs/strings/</a>.</td> + For details see <a href="http://www.cs.princeton.edu/%7Ers/strings/";>http://www.cs.princeton.edu/~rs/strings/</a>.<br>详 情请见 <a href="http://www.cs.princeton.edu/%7Ers/strings/";>http://www.cs.princeton.edu/~rs/strings/</a>.</td>
   </tr>
-</table>
-<p>Here are some sample declarations:</p>
-<pre><span class=identifier> </span><span class=identifier>symbols</span><span class=special>&lt;&gt; </span><span class=identifier>sym</span><span class=special>; - </span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=keyword>short</span><span class=special>, </span><span class=keyword>wchar_t</span><span class=special>&gt; </span><span class=identifier>sym2</span><span class=special>;
-
-    </span><span class=keyword>struct </span><span class=identifier>my_info
-    </span><span class=special>{
- </span><span class=keyword>int </span><span class=identifier>id</span><span class=special>; - </span><span class=keyword>double </span><span class=identifier>value</span><span class=special>;
-    </span><span class=special>};
-
- </span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=identifier>my_info</span><span class=special>&gt; </span><span class=identifier>sym3</span><span class=special>;</span></pre>
+</tbody></table>
+<p>Here are some sample declarations<br>以下是一些声明的例子</p>
+<pre><span class="identifier"> </span><span class="identifier">symbols</span><span class="special">&lt;&gt; </span><span class="identifier">sym</span><span class="special">;<br> </span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">short</span><span class="special">, </span><span class="keyword">wchar_t</span><span class="special">&gt; </span><span class="identifier">sym2</span><span class="special">;<br><br> </span><span class="keyword">struct </span><span class="identifier">my_info<br> </span><span class="special">{<br> </span><span class="keyword">int </span><span class="identifier">id</span><span class="special">;<br> </span><span class="keyword">double </span><span class="identifier">value</span><span class="special">;<br> </span><span class="special">};<br><br> </span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="identifier">my_info</span><span class="special">&gt; </span><span class="identifier">sym3</span><span class="special">;</span></pre> <p>After having declared our symbol tables, symbols may be added statically using
-  the construct:</p>
-<pre><span class=identifier> sym </span><span class=special>= </span><span class=identifier>a</span><span class=special>, </span><span class=identifier>b</span><span class=special>, </span><span class=identifier>c</span><span class=special>, </span><span class=identifier>d </span><span class=special>...;</span></pre> -<p>where <tt>sym</tt> is a symbol table and <tt>a..d</tt> etc. are strings. <img src="theme/note.gif" width="16" height="16">Note
+  the construct:<br>定义了我们的符号表之后,就可以用以下结构添加符号:</p>
+<pre><span class="identifier"> sym </span><span class="special">= </span><span class="identifier">a</span><span class="special">, </span><span class="identifier">b</span><span class="special">, </span><span class="identifier">c</span><span class="special">, </span><span class="identifier">d </span><span class="special">...;</span></pre> +<p>where <tt>sym</tt> is a symbol table and <tt>a..d</tt> etc. are strings. <img src="theme/note.gif" height="16" width="16">Note that the comma operator is separating the items being added to the symbol table, through an assignment. Due to operator overloading this is possible and correct (though it may take a little getting used to) and is a concise way to initialize the symbol table with many symbols. Also, it is perfectly valid to make multiple assignments to a symbol table to iteratively add symbols (or groups of symbols)
-  at different times.</p>
-<p>Simple example:<br>
+ at different times.<br>其中 <tt>sym</tt> 是一个符号表,<tt>a..d</tt> 等等 则是字符串。<img src="theme/note.gif" height="16" width="16">注意,多个符号 用逗号操作符分开,再通过赋值添加到符号表中。得益于操作符重载,使得这成为可 能,且正确实现(尽管可能需要一些习惯),而且这也是以多个符号初始化一个符号表的 简单方法。此外,也完全可以对一个符号表多次赋值,在不同的时间反复添加符号(或 符号组)。</p>
+<p>Simple example:<br>简单例子:<br>
 </p>
-<pre><span class=identifier> sym </span><span class=special>= </span><span class=string>&quot;pineapple&quot;</span><span class=special>, </span><span class=string>&quot;orange&quot;</span><span class=special>, </span><span class=string>&quot;banana&quot;</span><span class=special>, </span><span class=string>&quot;apple&quot;</span><span class=special>, </span><span class=string>&quot;mango&quot;</span><span class=special>;</span></pre> +<pre><span class="identifier"> sym </span><span class="special">= </span><span class="string">"pineapple"</span><span class="special">, </span><span class="string">"orange"</span><span class="special">, </span><span class="string">"banana"</span><span class="special">, </span><span class="string">"apple"</span><span class="special">, </span><span class="string">"mango"</span><span class="special">;</span></pre> <p>Note that it is invalid to add the same symbol multiple times to a symbol table, - though you may modify the value associated with a symbol artibrarily many times.</p>
-<p>Now, we may use sym in the grammar. Example:</p>
-<pre><span class=identifier> fruits </span><span class=special>= </span><span class=identifier>sym </span><span class=special>&gt;&gt; </span><span class=special>*(</span><span class=literal>',' </span><span class=special>&gt;&gt; </span><span class=identifier>sym</span><span class=special>);</span></pre> + though you may modify the value associated with a symbol artibrarily many times.<br>注意,将同一个符号多次添加到一个符号表中是无效的,虽然你可以 任意多次地修改与某个符号相关联的值。</p> +<p>Now, we may use sym in the grammar. Example:<br>现在,我们可以在语法中使 用 sym 了。例如:</p> +<pre><span class="identifier"> fruits </span><span class="special">= </span><span class="identifier">sym </span><span class="special">&gt;&gt; </span><span class="special">*(</span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">sym</span><span class="special">);</span></pre> <p>Alternatively, symbols may be added dynamically through the member functor - <tt>add</tt> (see <tt><a href="#symbol_inserter">symbol_inserter</a></tt> below). + <tt>add</tt> (see <tt><a href="symbols.html#symbol_inserter">symbol_inserter</a></tt> below). The member functor <tt>add</tt> may be attached to a parser as a semantic action
-  taking in a begin/end pair:</p>
-<pre><span class=identifier> p</span><span class=special>[</span><span class=identifier>sym</span><span class=special>.</span><span class=identifier>add</span><span class=special>]</span></pre>
+  taking in a begin/end pair:<br>另外,符号也可以通过成员仿函数
+ <tt>add</tt> (见下文的 <tt><a href="#symbol_inserter">symbol_inserter</a></tt>)来动态添加。成员仿函数 <tt>add</tt> 可以被作为接受一对 begin/end 的语义动作附加到一个分析器:</p> +<pre><span class="identifier"> p</span><span class="special">[</span><span class="identifier">sym</span><span class="special">.</span><span class="identifier">add</span><span class="special">]</span></pre> <p>where p is a parser (and sym is a symbol table). On success, the matching portion
-  of the input is added to the symbol table.</p>
-<p><tt>add</tt> may also be used to directly initialize data. Examples:</p>
-<pre><span class=identifier> sym</span><span class=special>.</span><span class=identifier>add</span><span class=special>(</span><span class=string>&quot;hello&quot;</span><span class=special>, </span><span class=number>1</span><span class=special>)(</span><span class=string>&quot;crazy&quot;</span><span class=special>, </span><span class=number>2</span><span class=special>)(</span><span class=string>&quot;world&quot;</span><span class=special>, </span><span class=number>3</span><span class=special>);</span></pre> -<p>Assuming of course that the data slot associated with <tt>sym</tt> is an integer.</p> + of the input is added to the symbol table.<br>其中 p 为一个分析器(且 sym 为一个符号表)。成功时,输入的匹配部分被添加到符号表中。</p> +<p><tt>add</tt> may also be used to directly initialize data. Examples:<br><tt>add</tt> 也可以被用于直接初始化数据。例如:</p> +<pre><span class="identifier"> sym</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span><span class="string">"hello"</span><span class="special">, </span><span class="number">1</span><span class="special">)(</span><span class="string">"crazy"</span><span class="special">, </span><span class="number">2</span><span class="special">)(</span><span class="string">"world"</span><span class="special">, </span><span class="number">3</span><span class="special">);</span></pre> +<p>Assuming of course that the data slot associated with <tt>sym</tt> is an integer.<br>当然,这要假设与 <tt>sym</tt> 关联的数据插槽是一个整数。</p> <p>The data associated with each symbol may be modified any time. The most obvious way of course is through <a href="semantic_actions.html">semantic actions</a>. A function or functor, as usual, may be attached to the symbol table. The symbol
-  table expects a function or functor compatible with the signature:</p>
-<p><b>Signature for functions:</b></p>
-<pre><code><font color="#000000"><span class=identifier> </span><span class=keyword>void </span><span class=identifier>func</span><span class=special>(</span><span class=identifier>T</span><span class="special">&amp;</span><span class=identifier> data</span><span class=special>);</span></font></code></pre>
-<p><b>Signature for functors:</b><br>
+ table expects a function or functor compatible with the signature:<br>与 每个符号相关联的数据可以随时被修改。当然,最明显的方法是通过 <a href="semantic_actions.html">语义动作</a> 来修改。通常,可以将一个函数或仿函 数附加至符号表。符号表要求该函数或仿函数兼容于以下签名:</p>
+<p><b>Signature for functions:&nbsp; 函数的签名:</b></p>
+<pre><code><font color="#000000"><span class="identifier"> </span><span class="keyword">void </span><span class="identifier">func</span><span class="special">(</span><span class="identifier">T</span><span class="special">&amp;</span><span class="identifier"> data</span><span class="special">);</span></font></code></pre>
+<p><b>Signature for functors: &nbsp;仿函数的签名:</b><br>
 </p>
-<pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>ftor
-    </span><span class=special>{
- </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>T</span><span class="special">&amp;</span><span class=identifier> data</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
-    </span><span class=special>};</span></font></code></pre>
+<pre><code><font color="#000000"><span class="special"> </span><span class="keyword">struct </span><span class="identifier">ftor<br> </span><span class="special">{<br> </span><span class="keyword">void </span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span><span class="special">&amp;</span><span class="identifier"> data</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};</span></font></code></pre> <p>Where <tt>T</tt> is the data type of the symbol table (the <tt>T</tt> in its template parameter list). When the symbol table successfully matches something from the input, the data associated with the matching entry in the symbol table
-  is reported to the semantic action.</p>
-<h2>Symbol table utilities</h2>
+ is reported to the semantic action.<br>其中 <tt>T</tt> 为符号表的数据类型 (即模板参数列表中的 <tt>T</tt>)。当符号表从输入中成功匹配出某些东西时,符号 表中与匹配项相关联的数据将被报告至语义动作。</p>
+<h2>Symbol table utilities 符号表工具</h2>
<p>Sometimes, one may wish to deal with the symbol table directly. Provided are
-  some symbol table utilities.</p>
-<p><b>add</b></p>
-<pre><span class=identifier> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SetT</span><span class=special>&gt; - </span><span class=identifier>T</span><span class=special>* </span><span class=identifier>add</span><span class=special>(</span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=identifier>CharT</span><span class=special>, </span><span class=identifier>SetT</span><span class=special>&gt;&amp; </span><span class=identifier>table</span><span class=special>, </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>sym</span><span class=special>, </span><span class=identifier>T </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>data </span><span class=special>= </span><span class=identifier>T</span><span class=special>());</span></pre> + some symbol table utilities.<br>有时,你可能希望直接处理符号表。我们提供 了一些符号表工具。</p>
+<p><b>add 添加</b></p>
+<pre><span class="identifier"> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">T</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SetT</span><span class="special">&gt;<br> </span><span class="identifier">T</span><span class="special">* </span><span class="identifier">add</span><span class="special">(</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">, </span><span class="identifier">CharT</span><span class="special">, </span><span class="identifier">SetT</span><span class="special">&gt;&amp; </span><span class="identifier">table</span><span class="special">, </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">sym</span><span class="special">, </span><span class="identifier">T </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">data </span><span class="special">= </span><span class="identifier">T</span><span class="special">());</span></pre> <p>adds a symbol <tt>sym</tt> (C string) to a symbol table <tt>table</tt> plus an optional data <tt>data</tt> associated with the symbol. Returns a pointer to the data associated with the symbol or <tt>NULL</tt> if add failed (e.g.
-  when the symbol is already added before).<br>
+ when the symbol is already added before).<br>将符号 <tt>sym</tt> (C字符串 )添加到符号表 <tt>table</tt> 并附加一个可选的数据 <tt>data</tt> 关联至该符 号。返回一个指向关联到该符号的数据的指针,如果失败(例如,该符号之前已被添加 )则返回 <tt>NULL</tt>。<br>
   <br>
-  <b>find</b></p>
-<pre><span class=special> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>T</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SetT</span><span class=special>&gt; - </span><span class=identifier>T</span><span class=special>* </span><span class=identifier>find</span><span class=special>(</span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=identifier>T</span><span class=special>, </span><span class=identifier>CharT</span><span class=special>, </span><span class=identifier>SetT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>table</span><span class=special>, </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>sym</span><span class=special>);</span></pre>
+  <b>find 查找</b></p>
+<pre><span class="special"> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">T</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SetT</span><span class="special">&gt;<br> </span><span class="identifier">T</span><span class="special">* </span><span class="identifier">find</span><span class="special">(</span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">, </span><span class="identifier">CharT</span><span class="special">, </span><span class="identifier">SetT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">table</span><span class="special">, </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">sym</span><span class="special">);</span></pre> <p>finds a symbol <tt>sym</tt> (C string) from a symbol table <tt>table</tt>. Returns a pointer to the data associated with the symbol or <tt>NULL</tt> if
-  not found</p>
+ not found<br>从符号表 <tt>table</tt> 中查找一个符号 <tt>sym</tt> (C字符串 )。返回一个指向关联到该符号的数据的指针,如果查找失败则返回 <tt>NULL</tt>。 </p>
 <h2><a name="symbol_inserter"></a>symbol_inserter</h2>
<p>The symbols class holds an instance of this class named <tt>add</tt>. This can be called directly just like a member function, passing in a first/last
-  iterator and optional data:<br>
+ iterator and optional data:<br>symbols 类中持有该类的一个名为 <tt>add</tt> 的实例。它可以象一个成员函数那样被直接调用,传入一对 first/last
+  迭代器以及可选的数据:<br>
   <br>
 </p>
-<pre><span class=identifier> sym</span><span class=special>.</span><span class=identifier>add</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>data</span><span class=special>);</span></pre>
-<p>Or, passing in a C string and optional data:<br>
+<pre><span class="identifier"> sym</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">, </span><span class="identifier">data</span><span class="special">);</span></pre> +<p>Or, passing in a C string and optional data:<br>或者,传入一个C字符串和 可选的数据:<br>
 </p>
-<pre><span class=identifier> sym</span><span class=special>.</span><span class=identifier>add</span><span class=special>(</span><span class=identifier>c_string</span><span class=special>, </span><span class=identifier>data</span><span class=special>);</span></pre> +<pre><span class="identifier"> sym</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span><span class="identifier">c_string</span><span class="special">, </span><span class="identifier">data</span><span class="special">);</span></pre> <p>where <tt>sym</tt> is a symbol table. The <tt>data</tt> argument is optional. The nice thing about this scheme is that it can be cascaded. We've seen this
-  applied above. Here's a snippet from the roman numerals parser</p>
-<pre> <span class=comment>// Parse roman numerals (1..9) using the symbol table.
-
-</span> <span class=keyword>struct </span><span class=identifier>ones </span><span class=special>: </span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=keyword>unsigned</span><span class=special>&gt;
-    </span><span class=special>{
-       </span><span class=identifier>ones</span><span class=special>()
-       </span><span class=special>{
-            </span><span class=identifier>add
- </span><span class=special>(</span><span class=string>&quot;I&quot; </span><span class=special>, </span><span class=number>1</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;II&quot; </span><span class=special>, </span><span class=number>2</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;III&quot; </span><span class=special>, </span><span class=number>3</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;IV&quot; </span><span class=special>, </span><span class=number>4</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;V&quot; </span><span class=special>, </span><span class=number>5</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;VI&quot; </span><span class=special>, </span><span class=number>6</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;VII&quot; </span><span class=special>, </span><span class=number>7</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;VIII&quot; </span><span class=special>, </span><span class=number>8</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;IX&quot; </span><span class=special>, </span><span class=number>9</span><span class=special>)
-               </span><span class=special>;
-       </span><span class=special>}
-
- </span><span class=special>} </span><span class=identifier>ones_p</span><span class=special>;</span></pre> + applied above. Here's a snippet from the roman numerals parser<br>其中 <tt>sym</tt> 是一个符号表。参数 <tt>data</tt> 是可选的。这种机制的好处是,它 可以级联。前面我们已经见过它的应用。以下是来自罗马数字分析器的代码片断</p> +<pre> <span class="comment">// Parse roman numerals (1..9) using the symbol table.<br><br></span> <span class="keyword">struct </span><span class="identifier">ones </span><span class="special">: </span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="keyword">unsigned</span><span class="special">&gt;<br> </span><span class="special">{<br> </span><span class="identifier">ones</span><span class="special">()<br> </span><span class="special">{<br> </span><span class="identifier">add<br> </span><span class="special">(</span><span class="string">"I" </span><span class="special">, </span><span class="number">1</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"II" </span><span class="special">, </span><span class="number">2</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"III" </span><span class="special">, </span><span class="number">3</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"IV" </span><span class="special">, </span><span class="number">4</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"V" </span><span class="special">, </span><span class="number">5</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"VI" </span><span class="special">, </span><span class="number">6</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"VII" </span><span class="special">, </span><span class="number">7</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"VIII" </span><span class="special">, </span><span class="number">8</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"IX" </span><span class="special">, </span><span class="number">9</span><span class="special">)<br> </span><span class="special">;<br> </span><span class="special">}<br><br> </span><span class="special">} </span><span class="identifier">ones_p</span><span class="special">;</span></pre> <p>Notice that a user defined struct <tt>ones</tt> is subclassed from <tt>symbols</tt>. - Then at construction time, we added all the symbols using the <tt>add</tt> symbol_inserter.</p> -<p> <img height="16" width="15" src="theme/lens.gif"> The full source code can be <a href="../example/fundamental/roman_numerals.cpp">viewed here</a>. This is part of the Spirit distribution.</p> + Then at construction time, we added all the symbols using the <tt>add</tt> symbol_inserter.<br>注意,用户自定义的结构 <tt>ones</tt> 是 <tt>symbols</tt> 的子类。在构造的时候,我们用 <tt>add</tt> symbol_inserter 添加所有符号。</p> +<p> <img src="theme/lens.gif" height="16" width="15"> The full source code can be <a href="../example/fundamental/roman_numerals.cpp">viewed here</a>. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 完整的源代码可以 <a href="../example/fundamental/roman_numerals.cpp">在此查看</a>。这是Spirit发 布包的一部分。</p> <p>Again, <tt>add</tt> may also be used as a semantic action since it conforms
-  to the action interface (see semantic actions):<br>
+ to the action interface (see semantic actions):<br>同样,<tt>add</tt> 也 可以被用作语义动作,因为它符合动作的接口(见语义动作):<br>
 </p>
-<pre><span class=special></span><span class=identifier> p</span><span class=special>[</span><span class=identifier>sym</span><span class=special>.</span><span class=identifier>add</span><span class=special>]</span></pre>
-<p>where p is a parser of course.<span class=special><br>
+<pre><span class="special"></span><span class="identifier"> p</span><span class="special">[</span><span class="identifier">sym</span><span class="special">.</span><span class="identifier">add</span><span class="special">]</span></pre> +<p>where p is a parser of course.<br>其中 p 当然是一个分析器了。<span class="special"><br>
   </span></p>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="distinct.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="trees.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/techniques.html      Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/techniques.html      Mon Oct 12 20:27:43 2009
@@ -1,100 +1,76 @@
-<html>
-<head>
-<title>Techniques</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<link rel="stylesheet" href="theme/style.css" type="text/css">
-</head>
-
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+
+<title>Techniques</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
-  <tr>
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
+  <tbody><tr>
     <td width="10">
     </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Techniques</b></font></td> - <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Techniques 技术</b></font></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="style_guide.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="faq.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <ul>
-  <li><a href="#templatized_functors">Templatized Functors</a></li>
- <li><a href="#multiple_scanner_support">Rule With Multiple Scanners</a></li> + <li><a href="#templatized_functors">Templatized Functors 模板化仿函数 </a></li> + <li><a href="#multiple_scanner_support">Rule With Multiple Scanners 带多 个扫描器的规则</a></li>
   <li><a href="#no_rules">Look Ma' No Rules!</a></li>
   <li><a href="#typeof">typeof</a></li>
   <li><a href="#nabialek_trick">Nabialek trick</a></li>
 </ul>
-<h3><a name="templatized_functors"></a> Templatized Functors</h3>
+<h3><a name="templatized_functors"></a> Templatized Functors 模板化仿函数 </h3> <p>For the sake of genericity, it is often better to make the functor's member <tt>operator()</tt> a template. That way, we do not have to concern ourselves with the type of the argument to expect as long as the behavior is appropriate. For instance, rather than hard-coding <tt>char const*</tt> as the argument of a generic semantic action, it is better to make it a template member function.
-  That way, it can accept any type of iterator:</p>
-<pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>my_functor
-    </span><span class=special>{
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>&gt; - </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>IteratorT </span><span class=identifier>first</span><span class=special>, </span><span class=identifier>IteratorT </span><span class=identifier>last</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
-    </span><span class=special>};</span></font></code></pre>
+ That way, it can accept any type of iterator:<br>从泛型的角度看,令仿函数 + <tt>operator()</tt> 成员模板化往往是较好的做法。这样,我们不必关心参数的 类型,只要其行为是适当的即可。例如,不要硬编码 <tt>char const*</tt>&nbsp;作 为一个通用的语义动作的参数,最好是使它成为一个模板成员函数。这样,它就可以接 受任意的迭代器类型:</p> +<pre><code><font color="#000000"><span class="special"> </span><span class="keyword">struct </span><span class="identifier">my_functor<br> </span><span class="special">{<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">&gt;<br> </span><span class="keyword">void </span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">IteratorT </span><span class="identifier">first</span><span class="special">, </span><span class="identifier">IteratorT </span><span class="identifier">last</span><span class="special">) </span><span class="keyword">const</span><span class="special">;<br> </span><span class="special">};</span></font></code></pre> <p>Take note that this is only possible with functors. It is not possible to pass in template functions as semantic actions unless you cast it to the correct function signature; in which case, you <em>monomorphize</em> the function. This
-  clearly shows that functors are superior to plain functions.</p>
+ clearly shows that functors are superior to plain functions.<br>注意,这 只对仿函数是可能的。不可能将模板函数作为语义动作传入,除非您将它转换为正确的 函数签名;在这种情况下,你monomorphize了该函数。这清楚地表明了,仿函数优于普 通的函数。</p> <h3><b><a name="multiple_scanner_support" id="multiple_scanner_support"></a> Rule
-  With Multiple Scanners</b></h3>
+  With Multiple Scanners 带多个扫描器的规则</b></h3>
<p>As of v1.8.0, rules can use one or more scanner types. There are cases, for instance, where we need a rule that can work on the phrase and character levels. Rule/scanner mismatch has been a source of confusion and is the no. 1 <a href="faq.html#scanner_business">FAQ</a>. To address this issue, we now have <a href="rule.html#multiple_scanner_support">multiple
-  scanner support</a>. </p>
+ scanner support</a>.<br>截至 v1.8.0,规则可以使用一个或多个扫描器类型。在 某些情况下,例如,我们需要一个可以工作于短语和字符层面的规则时。规则/扫描器 间的失配已一直是混乱的源头,也是首当其冲的 <a href="faq.html#scanner_business">FAQ</a>。为解决此问题,我们需要 <a href="rule.html#multiple_scanner_support">多扫描器支持</a>。 </p> <p>Here is an example of a grammar with a rule <tt>r</tt> that can be called with 3 types of scanners (phrase-level, lexeme, and lower-case). See the <a href="rule.html">rule</a>, <a href="grammar.html">grammar</a>, <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> - and <a href="scanner.html#as_lower_scanner">as_lower_scanner </a>for more information. + and <a href="scanner.html#as_lower_scanner">as_lower_scanner </a>for more information.<br>以下是一个语法例子,其中有一个规则 <tt>r</tt> 可用3个扫 描器类型调用(短语级别的、词位的和小写的)。更多信息请见 <a href="rule.html">规则</a>, + <a href="grammar.html">语法</a>, <a href="scanner.html#lexeme_scanner">lexeme_scanner</a> 和 <a href="scanner.html#as_lower_scanner">as_lower_scanner</a>。
 </p>
-<p>Here's the grammar (see <a href="../example/techniques/multiple_scanners.cpp">multiple_scanners.cpp</a>): +<p>Here's the grammar (see <a href="../example/techniques/multiple_scanners.cpp">multiple_scanners.cpp</a>):<br>以 下就是这个语法(见 <a href="../example/techniques/multiple_scanners.cpp">multiple_scanners.cpp</a>):
 </p>
-<pre><span class=special> </span><span class=keyword>struct </span><span class=identifier>my_grammar </span><span class=special>: </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>my_grammar</span><span class=special>&gt;
-    </span><span class=special>{
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>definition
-        </span><span class=special>{
- </span><span class=identifier>definition</span><span class=special>(</span><span class=identifier>my_grammar </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>self</span><span class=special>)
-            </span><span class=special>{
- </span><span class=identifier>r </span><span class=special>= </span><span class=identifier>lower_p</span><span class=special>; - </span><span class=identifier>rr </span><span class=special>= </span><span class=special>+(</span><span class=identifier>lexeme_d</span><span class=special>[</span><span class=identifier>r</span><span class=special>] </span><span class=special>&gt;&gt; </span><span class=identifier>as_lower_d</span><span class=special>[</span><span class=identifier>r</span><span class=special>] </span><span class=special>&gt;&gt; </span><span class=identifier>r</span><span class=special>);
-            </span><span class=special>}
-
- </span><span class=keyword>typedef </span><span class=identifier>scanner_list</span><span class=special>&lt;
-                </span><span class=identifier>ScannerT
- </span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>lexeme_scanner</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type - </span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>as_lower_scanner</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type - </span><span class=special>&gt; </span><span class=identifier>scanners</span><span class=special>;
-
- </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>scanners</span><span class=special>&gt; </span><span class=identifier>r</span><span class=special>; - </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>rr</span><span class=special>; - </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>start</span><span class=special>() </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>rr</span><span class=special>; </span><span class=special>}
-        </span><span class=special>};
-    </span><span class=special>};</span></pre>
+<pre><span class="special"> </span><span class="keyword">struct </span><span class="identifier">my_grammar </span><span class="special">: </span><span class="identifier">grammar</span><span class="special">&lt;</span><span class="identifier">my_grammar</span><span class="special">&gt;<br> </span><span class="special">{<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ScannerT</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">definition<br> </span><span class="special">{<br> </span><span class="identifier">definition</span><span class="special">(</span><span class="identifier">my_grammar </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">self</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="identifier">r </span><span class="special">= </span><span class="identifier">lower_p</span><span class="special">;<br> </span><span class="identifier">rr </span><span class="special">= </span><span class="special">+(</span><span class="identifier">lexeme_d</span><span class="special">[</span><span class="identifier">r</span><span class="special">] </span><span class="special">&gt;&gt; </span><span class="identifier">as_lower_d</span><span class="special">[</span><span class="identifier">r</span><span class="special">] </span><span class="special">&gt;&gt; </span><span class="identifier">r</span><span class="special">);<br> </span><span class="special">}<br><br> </span><span class="keyword">typedef </span><span class="identifier">scanner_list</span><span class="special">&lt;<br> </span><span class="identifier">ScannerT<br> </span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">lexeme_scanner</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt;::</span><span class="identifier">type<br> </span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">as_lower_scanner</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt;::</span><span class="identifier">type<br> </span><span class="special">&gt; </span><span class="identifier">scanners</span><span class="special">;<br><br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">scanners</span><span class="special">&gt; </span><span class="identifier">r</span><span class="special">;<br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt; </span><span class="identifier">rr</span><span class="special">;<br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">start</span><span class="special">() </span><span class="keyword">const </span><span class="special">{ </span><span class="keyword">return </span><span class="identifier">rr</span><span class="special">; </span><span class="special">}<br> </span><span class="special">};<br> </span><span class="special">};</span></pre>
 <p>By default support for multiple scanners is disabled.  The macro
   <tt>BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT</tt> must be defined to the
   maximum number of scanners allowed in a scanner_list.  The value must
   be greater than 1 to enable multiple scanners.  Given the
   example above, to define a limit of three scanners for the list, the
   following line must be inserted into the source file before the
-  inclusion of Spirit headers:
+  inclusion of Spirit headers:<br>缺省情况下,多扫描器支持是关闭的。宏
+ <tt>BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT</tt> 必须被定义为在一个 scanner_list 中允许的最大扫描器数量。该值必须大于1才能激活多扫描器。在以上例 子中,要定义扫描器列表中最多可有3个扫描器,以下一行必须插入到源文件中包含 Spirit头文件之前:
 </p>
-<pre><span class=special> </span><span class=preprocessor>#define </span><span class=identifier>BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT</span> <span class=literal>3</span></pre> -<h3><span class=special></span><b> <a name="no_rules" id="no_rules"></a> Look
-  Ma' No Rules</b></h3>
+<pre><span class="special"> </span><span class="preprocessor">#define </span><span class="identifier">BOOST_SPIRIT_RULE_SCANNERTYPE_LIMIT</span> <span class="literal">3</span></pre> +<h3><span class="special"></span><b> <a name="no_rules" id="no_rules"></a> Look
+  Ma' No Rules 看,不使用规则</b></h3>
<p>You use grammars and you use lots of 'em? Want a fly-weight, no-cholesterol,
-  super-optimized grammar? Read on...</p>
+ super-optimized grammar? Read on...<br>你使用语法且经常使用吗?想要一个轻 量级的、没有多余部分、超级优化的语法吗?继续读下去...</p> <p>I have a love-hate relationship with rules. I guess you know the reasons why. A lot of problems stem from the limitation of rules. Dynamic polymorphism and static polymorphism in C++ do not mix well. There is no notion of virtual template
@@ -102,272 +78,153 @@
specific scanner type</strong>. This results in problems such as the <a href="faq.html#scanner_business">scanner business</a>, our no. 1 FAQ. Apart from that, the virtual functions in rules slow down parsing, kill all meta-information, and kills inlining, hence bloating
-  the generated code, especially for very tiny rules such as:</p>
+ the generated code, especially for very tiny rules such as:<br>我对规则是 又爱又恨。我猜你应该知道其中的原因。许多问题是源于对规则的限制。动态多态性和 静态多态性在C++中未能很好地混合。在C++中,没有虚拟模板函数的概念;至少目前还 没有。因此,<strong>规则是针对某一特定的扫描器类型的</strong>。这导致了 <a href="faq.html#scanner_business">扫描器事务</a> 此类问题,我们第一的FAQ。此 外,规则中的虚拟函数降低了分析的速度,消灭了所有元信息,也消灭了内联,因此生 成的代码极度膨胀,尤其是对于非常微型的规则,如:</p> <pre> r <span class="special">=</span> ch_p<span class="special">(</span><span class="quotes">'x'</span><span class="special">) &gt;&gt;</span> uint_p<span class="special">;</span></pre> <p> The rule's limitation is the main reason why the grammar is designed the way it is now, with a nested template definition class. The rule's limitation is also the reason why subrules exists. But do we really need rules? Of course! Before C++ adopts some sort of auto-type deduction, such as that proposed by
-  David Abrahams in clc++m:</p>
-<pre>
- <code><span class=keyword>auto </span><span class=identifier>r </span><span class=special>= ...</span><span class=identifier>definition </span><span class=special>...</span></code></pre> + David Abrahams in clc++m:<br>这个规则的限制是语法为何以现有方式,嵌套模板 定义类,来设计的主要原因。这个规则的限制也是子规则为何存在的原因。但是,我们 真的需要规则吗?当然!在C++采用某各种自动类型推演,正如
+  David Abrahams 在 clc++m 中所建议的那样:</p>
+<pre> <code><span class="keyword">auto </span><span class="identifier">r </span><span class="special">= ...</span><span class="identifier">definition </span><span class="special">...</span></code></pre> <p> we are tied to the rule as RHS placeholders. However.... in some occasions
-  we can get by without rules! For instance, rather than writing:</p>
-<pre>
- <code><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>'x'</span><span class=special>);</span></code></pre>
-<p> It's better to write:</p>
-<pre>
- <code><span class=identifier>chlit</span><span class=special>&lt;&gt; </span><span class=identifier>x </span><span class=special>= </span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>'x'</span><span class=special>);</span></code></pre> + we can get by without rules! For instance, rather than writing:<br>之 前,我们只能绑定在规则上,作为RHS占位符。但是....在某些场合,我们可以不需要 规则!例如,与其这样写:</p> +<pre> <code><span class="identifier">rule</span><span class="special">&lt;&gt; </span><span class="identifier">x </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'x'</span><span class="special">);</span></code></pre>
+<p> It's better to write:<br>不如这样写更好:</p>
+<pre> <code><span class="identifier">chlit</span><span class="special">&lt;&gt; </span><span class="identifier">x </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'x'</span><span class="special">);</span></code></pre> <p> That's trivial. But what if the rule is rather complicated? Ok, let's proceed stepwise... I'll investigate a simple skip_parser based on the C grammar from - Hartmut Kaiser. Basically, the grammar is written as (see <a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a>):</p> -<pre><code> <span class=keyword>struct </span><span class=identifier>skip_grammar </span><span class=special>: </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>skip_grammar</span><span class=special>&gt;
-    {
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>definition
-        </span><span class=special>{
- </span><span class=identifier>definition</span><span class=special>(</span><span class=identifier>skip_grammar </span><span class=keyword>const</span><span class=special>&amp; /*</span><span class=identifier>self</span><span class=special>*/)
-            {
-                </span><span class=identifier>skip
- </span><span class=special>= </span><span class=identifier>space_p - </span><span class=special>| </span><span class=string>&quot;//&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=literal>'\n'</span><span class=special>) &gt;&gt; </span><span class=literal>'\n' - </span><span class=special>| </span><span class=string>&quot;/*&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=string>&quot;*/&quot;</span><span class=special>) &gt;&gt; </span><span class=string>&quot;*/&quot;
-                    </span><span class=special>;
-            }
-
- </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>skip</span><span class=special>;
-
- </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; - </span><span class=identifier>start</span><span class=special>() </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>skip</span><span class=special>; }
-        };
-    };</span></code></pre>
+ Hartmut Kaiser. Basically, the grammar is written as (see <a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a>):<br>这 很平常。不过,如果规则比较复杂呢?好的,我们继续向前... 我将探讨一个基于C语 法的简单 skip_parser,它来自 + Hartmut Kaiser。基本上,这个语法可以写成(见 <a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a>):</p> +<pre><code> <span class="keyword">struct </span><span class="identifier">skip_grammar </span><span class="special">: </span><span class="identifier">grammar</span><span class="special">&lt;</span><span class="identifier">skip_grammar</span><span class="special">&gt;<br> {<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ScannerT</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">definition<br> </span><span class="special">{<br> </span><span class="identifier">definition</span><span class="special">(</span><span class="identifier">skip_grammar </span><span class="keyword">const</span><span class="special">&amp; /*</span><span class="identifier">self</span><span class="special">*/)<br> {<br> </span><span class="identifier">skip<br> </span><span class="special">= </span><span class="identifier">space_p<br> </span><span class="special">| </span><span class="string">"//" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="literal">'\n'</span><span class="special">) &gt;&gt; </span><span class="literal">'\n'<br> </span><span class="special">| </span><span class="string">"/*" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="string">"*/"</span><span class="special">) &gt;&gt; </span><span class="string">"*/"<br> </span><span class="special">;<br> }<br><br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt; </span><span class="identifier">skip</span><span class="special">;<br><br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">ScannerT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp;<br> </span><span class="identifier">start</span><span class="special">() </span><span class="keyword">const </span><span class="special">{ </span><span class="keyword">return </span><span class="identifier">skip</span><span class="special">; }<br> };<br> };</span></code></pre> <p> Ok, so far so good. Can we do better? Well... since there are no recursive rules there (in fact there's only one rule), you can expand the type of rule's - RHS as the rule type (see <a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a>):</p> -<pre><code><span class=special> </span><span class=keyword>struct </span><span class=identifier>skip_grammar </span><span class=special>: </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>skip_grammar</span><span class=special>&gt;
-    {
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>definition
-        </span><span class=special>{
-</span> <span class=identifier>definition</span><span class=special>(</span><span class=identifier>skip_grammar </span><span class=keyword>const</span><span class=special>&amp; /*</span><span class=identifier>self</span><span class=special>*/)
-            : </span><span class=identifier>skip</span><span class=special>
-                (       </span><span class=identifier>space_p
- </span><span class=special>| </span><span class=string>&quot;//&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=literal>'\n'</span><span class=special>) &gt;&gt; </span><span class=literal>'\n' - </span><span class=special>| </span><span class=string>&quot;/*&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=string>&quot;*/&quot;</span><span class=special>) &gt;&gt; </span><span class=string>&quot;*/&quot;
-                </span><span class=special>)
-            {
-            }
-
-            </span><span class=keyword>typedef
- </span><span class=identifier>alternative</span><span class=special>&lt;</span><span class=identifier>alternative</span><span class=special>&lt;</span><span class=identifier>space_parser</span><span class=special>, </span><span class=identifier>sequence</span><span class=special>&lt;</span><span class=identifier>sequence</span><span class=special>&lt; - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt;, </span><span class=identifier>kleene_star</span><span class=special>&lt;</span><span class=identifier>difference</span><span class=special>&lt;</span><span class=identifier>anychar_parser</span><span class=special>, - </span><span class=identifier>chlit</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>&gt; &gt; &gt; &gt;, </span><span class=identifier>chlit</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>&gt; &gt; &gt;, </span><span class=identifier>sequence</span><span class=special>&lt;</span><span class=identifier>sequence</span><span class=special>&lt; - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt;, </span><span class=identifier>kleene_star</span><span class=special>&lt;</span><span class=identifier>difference</span><span class=special>&lt;</span><span class=identifier>anychar_parser</span><span class=special>, - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt; &gt; &gt; &gt;, </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt; &gt; &gt; - </span><span class=identifier>skip_t</span><span class=special>; -</span><span class=special> </span><span class=identifier>skip_t </span><span class=identifier>skip</span><span class=special>;
-
- </span><span class=identifier>skip_t </span><span class=keyword>const</span><span class=special>&amp; - </span><span class=identifier>start</span><span class=special>() </span><span class=keyword>const </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>skip</span><span class=special>; }
-        };
-    };</span></code></pre>
+ RHS as the rule type (see <a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a>):<br>好 的,不错。我们可以做得更好吗?嗯... 由于这里没有递归的规则(事实上只有一个规 则),你可以将规则的RHS类型扩展为规则的类型(见 <a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a>):</p> +<pre><code><span class="special"> </span><span class="keyword">struct </span><span class="identifier">skip_grammar </span><span class="special">: </span><span class="identifier">grammar</span><span class="special">&lt;</span><span class="identifier">skip_grammar</span><span class="special">&gt;<br> {<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ScannerT</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">definition<br> </span><span class="special">{<br></span> <span class="identifier">definition</span><span class="special">(</span><span class="identifier">skip_grammar </span><span class="keyword">const</span><span class="special">&amp; /*</span><span class="identifier">self</span><span class="special">*/)<br> : </span><span class="identifier">skip</span><span class="special"> + ( </span><span class="identifier">space_p<br> </span><span class="special">| </span><span class="string">"//" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="literal">'\n'</span><span class="special">) &gt;&gt; </span><span class="literal">'\n'<br> </span><span class="special">| </span><span class="string">"/*" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="string">"*/"</span><span class="special">) &gt;&gt; </span><span class="string">"*/"<br> </span><span class="special">)<br> {<br> }<br><br> </span><span class="keyword">typedef<br> </span><span class="identifier">alternative</span><span class="special">&lt;</span><span class="identifier">alternative</span><span class="special">&lt;</span><span class="identifier">space_parser</span><span class="special">, </span><span class="identifier">sequence</span><span class="special">&lt;</span><span class="identifier">sequence</span><span class="special">&lt;<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt;, </span><span class="identifier">kleene_star</span><span class="special">&lt;</span><span class="identifier">difference</span><span class="special">&lt;</span><span class="identifier">anychar_parser</span><span class="special">,<br> </span><span class="identifier">chlit</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt; &gt; &gt; &gt;, </span><span class="identifier">chlit</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt; &gt; &gt;, </span><span class="identifier">sequence</span><span class="special">&lt;</span><span class="identifier">sequence</span><span class="special">&lt;<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt;, </span><span class="identifier">kleene_star</span><span class="special">&lt;</span><span class="identifier">difference</span><span class="special">&lt;</span><span class="identifier">anychar_parser</span><span class="special">,<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt; &gt; &gt; &gt;, </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt; &gt; &gt;<br> </span><span class="identifier">skip_t</span><span class="special">;<br></span><span class="special"> </span><span class="identifier">skip_t </span><span class="identifier">skip</span><span class="special">;<br><br> </span><span class="identifier">skip_t </span><span class="keyword">const</span><span class="special">&amp;<br> </span><span class="identifier">start</span><span class="special">() </span><span class="keyword">const </span><span class="special">{ </span><span class="keyword">return </span><span class="identifier">skip</span><span class="special">; }<br> };<br> };</span></code></pre> <p> Ughhh! How did I do that? How was I able to get at the complex typedef? Am I insane? Well, not really... there's a trick! What you do is define the typedef
-  <tt>skip_t</tt> first as int:</p>
-<pre>
- <code><span class=keyword>typedef </span><span class=keyword>int </span><span class=identifier>skip_t</span><span class=special>;</span></code></pre> + <tt>skip_t</tt> first as int:<br>Ughhh! 我是怎么做的呢?我怎么能得到这个 复杂的 typedef? 我疯了吗?嗯,这不是真的... 这里有个诀窍!你要做的就是首先定 义 typedef
+  <tt>skip_t</tt> 为 int:</p>
+<pre> <code><span class="keyword">typedef </span><span class="keyword">int </span><span class="identifier">skip_t</span><span class="special">;</span></code></pre> <p> Try to compile. Then, the compiler will generate an obnoxious error message
-  such as:</p>
-<pre>
- <code><span class=string>&quot;cannot convert boost::spirit::alternative&lt;... blah blah...to int&quot;</span><span class=special>.</span></code></pre>
+  such as:<br>试着编译一下。然后,编译器会生成一个可恶的错误信息如下:</p>
+<pre> <code><span class="string">"cannot convert boost::spirit::alternative&lt;... blah blah...to int"</span><span class="special">.</span></code></pre> <p> <strong>THERE YOU GO!</strong> You got it's type! I just copy and paste the
-  correct type (removing explicit qualifications, if preferred).</p>
+ correct type (removing explicit qualifications, if preferred).<br><strong>做到了!</strong>你得到了它的类型!我只需复制并粘贴这 个正确的类型即可(删去显式的限定符,如果愿意的话)。</p> <p> Can we still go further? Yes. Remember that the grammar was designed for rules. The nested template definition class is needed to get around the rule's limitations. Without rules, I propose a new class called <tt>sub_grammar</tt>, the grammar's
-  low-fat counterpart:</p>
-<pre><code><span class=special> </span><span class=keyword>namespace </span><span class=identifier>boost </span><span class=special>{ </span><span class=keyword>namespace </span><span class=identifier>spirit
-    </span><span class=special>{
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>DerivedT</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>sub_grammar </span><span class=special>: </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>DerivedT</span><span class=special>&gt;
-        {
- </span><span class=keyword>typedef </span><span class=identifier>sub_grammar </span><span class=identifier>self_t</span><span class=special>; - </span><span class=keyword>typedef </span><span class=identifier>DerivedT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>embed_t</span><span class=special>;
-
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>result
-            </span><span class=special>{
- </span><span class=keyword>typedef </span><span class=keyword>typename </span><span class=identifier>parser_result</span><span class=special>&lt; - </span><span class=keyword>typename </span><span class=identifier>DerivedT</span><span class=special>::</span><span class=identifier>start_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type - </span><span class=identifier>type</span><span class=special>;
-            };
-
- </span><span class=identifier>DerivedT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>derived</span><span class=special>() </span><span class=keyword>const - </span><span class=special>{ </span><span class=keyword>return </span><span class=special>*</span><span class=keyword>static_cast</span><span class=special>&lt;</span><span class=identifier>DerivedT </span><span class=keyword>const</span><span class=special>*&gt;(</span><span class=keyword>this</span><span class=special>); }
-
- </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ScannerT</span><span class=special>&gt; - </span><span class=keyword>typename </span><span class=identifier>parser_result</span><span class=special>&lt;</span><span class=identifier>self_t</span><span class=special>, </span><span class=identifier>ScannerT</span><span class=special>&gt;::</span><span class=identifier>type - </span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>ScannerT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>scan</span><span class=special>) </span><span class=keyword>const
-            </span><span class=special>{
- </span><span class=keyword>return </span><span class=identifier>derived</span><span class=special>().</span><span class=identifier>start</span><span class=special>.</span><span class=identifier>parse</span><span class=special>(</span><span class=identifier>scan</span><span class=special>);
-            }
-        };
-    }}</span></code></pre>
+ low-fat counterpart:<br>我们还可以走得更远吗?是的。记住,语法是为规则而 设计的。内嵌的模板定义类是必需的,以绕过规则的限制。没有规则,我提议一个名 为 <tt>sub_grammar</tt> 的新类,该语法的轻量级方式:</p> +<pre><code><span class="special"> </span><span class="keyword">namespace </span><span class="identifier">boost </span><span class="special">{ </span><span class="keyword">namespace </span><span class="identifier">spirit<br> </span><span class="special">{<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">DerivedT</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">sub_grammar </span><span class="special">: </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">DerivedT</span><span class="special">&gt;<br> {<br> </span><span class="keyword">typedef </span><span class="identifier">sub_grammar </span><span class="identifier">self_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">DerivedT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">embed_t</span><span class="special">;<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ScannerT</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">result<br> </span><span class="special">{<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">parser_result</span><span class="special">&lt;<br> </span><span class="keyword">typename </span><span class="identifier">DerivedT</span><span class="special">::</span><span class="identifier">start_t</span><span class="special">, </span><span class="identifier">ScannerT</span><span class="special">&gt;::</span><span class="identifier">type<br> </span><span class="identifier">type</span><span class="special">;<br> };<br><br> </span><span class="identifier">DerivedT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">derived</span><span class="special">() </span><span class="keyword">const<br> </span><span class="special">{ </span><span class="keyword">return </span><span class="special">*</span><span class="keyword">static_cast</span><span class="special">&lt;</span><span class="identifier">DerivedT </span><span class="keyword">const</span><span class="special">*&gt;(</span><span class="keyword">this</span><span class="special">); }<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ScannerT</span><span class="special">&gt;<br> </span><span class="keyword">typename </span><span class="identifier">parser_result</span><span class="special">&lt;</span><span class="identifier">self_t</span><span class="special">, </span><span class="identifier">ScannerT</span><span class="special">&gt;::</span><span class="identifier">type<br> </span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">ScannerT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">scan</span><span class="special">) </span><span class="keyword">const<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">derived</span><span class="special">().</span><span class="identifier">start</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">scan</span><span class="special">);<br> }<br> };<br> }}</span></code></pre> <p>With the <tt>sub_grammar</tt> class, we can define our skipper grammar this - way (see <a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a>):</p> -<pre><code><span class=special> </span><span class=keyword>struct </span><span class=identifier>skip_grammar </span><span class=special>: </span><span class=identifier>sub_grammar</span><span class=special>&lt;</span><span class=identifier>skip_grammar</span><span class=special>&gt;
-    {
-        </span><span class=keyword>typedef
- </span><span class=identifier>alternative</span><span class=special>&lt;</span><span class=identifier>alternative</span><span class=special>&lt;</span><span class=identifier>space_parser</span><span class=special>, </span><span class=identifier>sequence</span><span class=special>&lt;</span><span class=identifier>sequence</span><span class=special>&lt; - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt;, </span><span class=identifier>kleene_star</span><span class=special>&lt;</span><span class=identifier>difference</span><span class=special>&lt;</span><span class=identifier>anychar_parser</span><span class=special>, - </span><span class=identifier>chlit</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>&gt; &gt; &gt; &gt;, </span><span class=identifier>chlit</span><span class=special>&lt;</span><span class=keyword>char</span><span class=special>&gt; &gt; &gt;, </span><span class=identifier>sequence</span><span class=special>&lt;</span><span class=identifier>sequence</span><span class=special>&lt; - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt;, </span><span class=identifier>kleene_star</span><span class=special>&lt;</span><span class=identifier>difference</span><span class=special>&lt;</span><span class=identifier>anychar_parser</span><span class=special>, - </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt; &gt; &gt; &gt;, </span><span class=identifier>strlit</span><span class=special>&lt;</span><span class=keyword>const </span><span class=keyword>char</span><span class=special>*&gt; &gt; &gt;
-        </span><span class=identifier>start_t</span><span class=special>;
-
- </span><span class=identifier>skip_grammar</span><span class=special>()
-        : </span><span class=identifier>start
-            </span><span class=special>(
-                </span><span class=identifier>space_p
- </span><span class=special>| </span><span class=string>&quot;//&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=literal>'\n'</span><span class=special>) &gt;&gt; </span><span class=literal>'\n' - </span><span class=special>| </span><span class=string>&quot;/*&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=string>&quot;*/&quot;</span><span class=special>) &gt;&gt; </span><span class=string>&quot;*/&quot;
-            </span><span class=special>)
-        {}
-
- </span><span class=identifier>start_t </span><span class=identifier>start</span><span class=special>;
-    };</span></code></pre>
+ way (see <a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a>):<br>有 了这个 <tt>sub_grammar</tt> 类,我们可以按以下方式定义我们的跳读语法(见 <a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a>):</p> +<pre><code><span class="special"> </span><span class="keyword">struct </span><span class="identifier">skip_grammar </span><span class="special">: </span><span class="identifier">sub_grammar</span><span class="special">&lt;</span><span class="identifier">skip_grammar</span><span class="special">&gt;<br> {<br> </span><span class="keyword">typedef<br> </span><span class="identifier">alternative</span><span class="special">&lt;</span><span class="identifier">alternative</span><span class="special">&lt;</span><span class="identifier">space_parser</span><span class="special">, </span><span class="identifier">sequence</span><span class="special">&lt;</span><span class="identifier">sequence</span><span class="special">&lt;<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt;, </span><span class="identifier">kleene_star</span><span class="special">&lt;</span><span class="identifier">difference</span><span class="special">&lt;</span><span class="identifier">anychar_parser</span><span class="special">,<br> </span><span class="identifier">chlit</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt; &gt; &gt; &gt;, </span><span class="identifier">chlit</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt; &gt; &gt;, </span><span class="identifier">sequence</span><span class="special">&lt;</span><span class="identifier">sequence</span><span class="special">&lt;<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt;, </span><span class="identifier">kleene_star</span><span class="special">&lt;</span><span class="identifier">difference</span><span class="special">&lt;</span><span class="identifier">anychar_parser</span><span class="special">,<br> </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt; &gt; &gt; &gt;, </span><span class="identifier">strlit</span><span class="special">&lt;</span><span class="keyword">const </span><span class="keyword">char</span><span class="special">*&gt; &gt; &gt;<br> </span><span class="identifier">start_t</span><span class="special">;<br><br> </span><span class="identifier">skip_grammar</span><span class="special">()<br> : </span><span class="identifier">start<br> </span><span class="special">(<br> </span><span class="identifier">space_p<br> </span><span class="special">| </span><span class="string">"//" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="literal">'\n'</span><span class="special">) &gt;&gt; </span><span class="literal">'\n'<br> </span><span class="special">| </span><span class="string">"/*" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="string">"*/"</span><span class="special">) &gt;&gt; </span><span class="string">"*/"<br> </span><span class="special">)<br> {}<br><br> </span><span class="identifier">start_t </span><span class="identifier">start</span><span class="special">;<br> };</span></code></pre> <p>But what for, you ask? You can simply use the <tt>start_t</tt> type above as-is.
-  It's already a parser! We can just type:</p>
-<pre>
- <code><span class=identifier>skipper_t </span><span class=identifier>skipper </span><span class=special>=
-        </span><span class=identifier>space_p
- </span><span class=special>| </span><span class=string>&quot;//&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=literal>'\n'</span><span class=special>) &gt;&gt; </span><span class=literal>'\n' </span><br> <span class=special>| </span><span class=string>&quot;/*&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=string>&quot;*/&quot;</span><span class=special>) &gt;&gt; </span><span class=string>&quot;*/&quot;</span>
-    <span class=special>    ;</span></code></pre>
+ It's already a parser! We can just type:<br>但是这该怎么用,你会问?你可 以如上只使用 <tt>start_t</tt> 类型。它已经是一个分析器了!我们可以只输 入:</p> +<pre> <code><span class="identifier">skipper_t </span><span class="identifier">skipper </span><span class="special">=<br> </span><span class="identifier">space_p<br> </span><span class="special">| </span><span class="string">"//" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="literal">'\n'</span><span class="special">) &gt;&gt; </span><span class="literal">'\n' </span><br> <span class="special">| </span><span class="string">"/*" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="string">"*/"</span><span class="special">) &gt;&gt; </span><span class="string">"*/"</span>
+    <span class="special">    ;</span></code></pre>
<p> and use <tt>skipper</tt> just as we would any parser? Well, a subtle difference is that <tt>skipper</tt>, used this way will be embedded <strong>by value </strong>when<strong> </strong>you compose more complex parsers using it. That is, if we use <tt>skipper</tt> inside another production, the whole thing will be stored in the composite.
-  Heavy!</p>
-<p> The proposed <tt>sub_grammar</tt> OTOH will be held by reference. Note:</p> -<pre><code> <span class=keyword>typedef </span><span class=identifier>DerivedT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>embed_t</span><span class=special>;</span></code></pre> + Heavy!<br>仅将 <tt>skipper</tt> 用作我们所需的分析器?那么,一个微妙的区 别在于,以该方式使用 <tt>skipper</tt>,当你用它组成更复杂的分析器时它是 <strong>以值方式</strong>嵌入的。即,如果我们在另一个分析器中使用 <tt>skipper</tt>,整个东西都将被保存在组合物中。这有点太沉重了!</p> +<p> The proposed <tt>sub_grammar</tt> OTOH will be held by reference. Note:<br>另一方面,这个建议的 <tt>sub_grammar</tt> 应该以引用方式保存。 如:</p> +<pre><code> <span class="keyword">typedef </span><span class="identifier">DerivedT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">embed_t</span><span class="special">;</span></code></pre> <p>The proposed <tt>sub_grammar</tt> does not have the inherent limitations of rules, is very lighweight, and should be blazingly fast (can be fully inlined and does not use virtual functions). Perhaps this class will be part of a future
-  spirit release. </p>
-<table width="80%" border="0" align="center">
-  <tr>
- <td class="note_box"><img src="theme/note.gif" width="16" height="16"> <strong>The
-      no-rules result</strong><br> <br>
+ spirit release.<br>这个建议的 <tt>sub_grammar</tt> 没有规则的固有限制,非 常轻量,也应极其快速(完全可以内联且不使用虚拟函数)。也许这个类会是未来版本的 spirit的一部分。 </p>
+<table align="center" border="0" width="80%">
+  <tbody><tr>
+ <td class="note_box"><img src="theme/note.gif" height="16" width="16"> <strong>The
+      no-rules result 无规则的结果</strong><br> <br>
So, how much did we save? On MSVCV7.1, the original code: <a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a> compiles to <strong>28k</strong>. Eliding rules, <a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a>, we got <strong>24k</strong>. Not bad, we shaved off 4k amounting to a 14% reduction. But you'll be in for a surprise. The last version, using the sub-grammar: <a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a>, - compiles to <strong>5.5k</strong>! That's a whopping 80% reduction.<br> + compiles to <strong>5.5k</strong>! That's a whopping 80% reduction.<br>那么,我们节省了多少呢?在MSVCV7.1上,原来的代码 <a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a> + 编译后有 <strong>28k</strong>。不用规则的&nbsp;<a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a> 则是 <strong>24k</strong>。不错,我们砍掉了4k,减小了14%。不过你会更加惊讶。最后 一个版本,使用子语法的 <a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a>
+      编译后只有 <strong>5.5k</strong>! 高达80%的缩减。<br>
       <br>
-      <table width="100%" border="1">
-        <tr>
+      <table border="1" width="100%">
+        <tbody><tr>
<td><a href="../example/techniques/no_rules/no_rule1.cpp">no_rule1.cpp</a></td>
           <td><strong>28k</strong></td>
-          <td>standard rule and grammar</td>
+          <td>standard rule and grammar 标准规则和语法</td>
         </tr>
         <tr>
<td><a href="../example/techniques/no_rules/no_rule2.cpp">no_rule2.cpp</a></td>
           <td><strong>24k</strong></td>
-          <td>standard grammar, no rule</td>
+          <td>standard grammar, no rule 标准语法,无规则</td>
         </tr>
         <tr>
<td><a href="../example/techniques/no_rules/no_rule3.cpp">no_rule3.cpp</a></td>
           <td><strong>5.5k</strong></td>
-          <td>sub_grammar, no rule, no grammar</td>
+          <td>sub_grammar, no rule, no grammar 子语法,无规则,无语法</td>
         </tr>
-      </table> </td>
+      </tbody></table> </td>
   </tr>
-</table>
+</tbody></table>
 <h3><b> <a name="typeof" id="typeof"></a> typeof</b></h3>
<p>Some compilers already support the <tt>typeof</tt> keyword. Examples are g++ and Metrowerks CodeWarrior. Someday, <tt>typeof</tt> will become commonplace. It is worth noting that we can use <tt>typeof</tt> to define non-recursive rules without using the rule class. To give an example, we'll use the skipper example above; this time using <tt>typeof</tt>. First, to avoid redundancy, we'll introduce
-  a macro <tt>RULE</tt>: </p>
-<pre><code> <span class=preprocessor>#define </span><span class=identifier>RULE</span><span class=special>(</span><span class=identifier>name</span><span class=special>, </span><span class=identifier>definition</span><span class=special>) </span><span class="keyword">typeof</span><span class=special>(</span><span class=identifier>definition</span><span class=special>) </span><span class=identifier>name </span><span class=special>= </span><span class=identifier>definition</span></code></pre>
-<p>Then, simply:</p>
-<pre><code><span class=identifier> </span><span class=identifier>RULE</span><span class=special>(
-        </span><span class=identifier>skipper</span><span class=special>,
-        (       </span><span class=identifier>space_p
- </span><span class=special>| </span><span class=string>&quot;//&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=literal>'\n'</span><span class=special>) &gt;&gt; </span><span class=literal>'\n' - </span><span class=special>| </span><span class=string>&quot;/*&quot; </span><span class=special>&gt;&gt; *(</span><span class=identifier>anychar_p </span><span class=special>- </span><span class=string>&quot;*/&quot;</span><span class=special>) &gt;&gt; </span><span class=string>&quot;*/&quot;
-        </span><span class=special>)
-    );</span></code></pre>
-<p>(see <a href="../example/techniques/typeof.cpp">typeof.cpp</a>)</p>
+ a macro <tt>RULE</tt>:<br>有些编译器已经支持 <tt>typeof</tt> 关键字。例 如 g++ 和 Metrowerks CodeWarrior。迟早,<tt>typeof</tt> 会被广泛支持。值得注 意的是,我们可以用 <tt>typeof</tt> 来定义非递归规则而无需使用规则类。举个例 子,我们将使用前面的跳读器例子;这次使用 <tt>typeof</tt>。首先,为了避免重 复,我们引入一个宏 <tt>RULE</tt>: </p> +<pre><code> <span class="preprocessor">#define </span><span class="identifier">RULE</span><span class="special">(</span><span class="identifier">name</span><span class="special">, </span><span class="identifier">definition</span><span class="special">) </span><span class="keyword">typeof</span><span class="special">(</span><span class="identifier">definition</span><span class="special">) </span><span class="identifier">name </span><span class="special">= </span><span class="identifier">definition</span></code></pre>
+<p>Then, simply:<br>然后,只需:</p>
+<pre><code><span class="identifier"> </span><span class="identifier">RULE</span><span class="special">(<br> </span><span class="identifier">skipper</span><span class="special">,<br> ( </span><span class="identifier">space_p<br> </span><span class="special">| </span><span class="string">"//" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="literal">'\n'</span><span class="special">) &gt;&gt; </span><span class="literal">'\n'<br> </span><span class="special">| </span><span class="string">"/*" </span><span class="special">&gt;&gt; *(</span><span class="identifier">anychar_p </span><span class="special">- </span><span class="string">"*/"</span><span class="special">) &gt;&gt; </span><span class="string">"*/"<br> </span><span class="special">)<br> );</span></code></pre> +<p>(see <a href="../example/techniques/typeof.cpp">typeof.cpp</a>)<br>(见 <a href="../example/techniques/typeof.cpp">typeof.cpp</a>)</p> <p>That's it! Now you can use skipper just as you would any parser. Be reminded, however, that <tt>skipper</tt> above will be embedded by value when<strong> - </strong>you compose more complex parsers using it (see <tt>sub_grammar</tt> rationale above). You can use the <tt>sub_grammar</tt> class to avoid this problem.</p> + </strong>you compose more complex parsers using it (see <tt>sub_grammar</tt> rationale above). You can use the <tt>sub_grammar</tt> class to avoid this problem.<br>就是这样!现在你可以象任意分析器那样使用 skipper。不过要记住,当你使用以上的 <tt>skipper</tt> 来合成更为复杂的分析器 时,它是以值方式嵌入的(见前文的 <tt>sub_grammar</tt> 原理)。你可以使用 <tt>sub_grammar</tt> 类来避免这个问题。</p>
 <h3><a name="nabialek_trick"></a> Nabialek trick</h3>
-<p>This technique, I'll call the <strong><em>&quot;Nabialek trick&quot; </em></strong>(from the name of its inventor, Sam Nabialek), can improve the rule dispatch from linear non-deterministic to deterministic. The trick applies to grammars where a keyword (operator, etc), precedes a production. There are lots of grammars similar to this:</p>
-<pre>    <span class=identifier>r </span><span class=special>=
- </span><span class=identifier>keyword1 </span><span class=special>&gt;&gt; </span><span class=identifier>production1 - </span><span class=special>| </span><span class=identifier>keyword2 </span><span class=special>&gt;&gt; </span><span class=identifier>production2 - </span><span class=special>| </span><span class=identifier>keyword3 </span><span class=special>&gt;&gt; </span><span class=identifier>production3 - </span><span class=special>| </span><span class=identifier>keyword4 </span><span class=special>&gt;&gt; </span><span class=identifier>production4 - </span><span class=special>| </span><span class=identifier>keyword5 </span><span class=special>&gt;&gt; </span><span class=identifier>production5
-        </span><span class=comment>/*** etc ***/
-        </span><span class=special>;</span></pre>
-<p>The cascaded alternatives are tried one at a time through trial and error until something matches. The Nabialek trick takes advantage of the <a href="symbols.html">symbol table</a>'s search properties to optimize the dispatching of the alternatives. For an example, see <a href="../example/techniques/nabialek.cpp">nabialek.cpp</a>. The grammar works as follows. There are two rules (<tt>one</tt> and <tt>two</tt>). When &quot;one&quot; is recognized, rule <tt>one</tt> is invoked. When &quot;two&quot; is recognized, rule <tt>two</tt> is invoked. Here's the grammar:</p> -<pre><span class=special> </span><span class=identifier>one </span><span class=special>= </span><span class=identifier>name</span><span class=special>; - </span><span class=identifier>two </span><span class=special>= </span><span class=identifier>name </span><span class=special>&gt;&gt; </span><span class=literal>',' </span><span class=special>&gt;&gt; </span><span class=identifier>name</span><span class=special>;
-
- </span><span class=identifier>continuations</span><span class=special>.</span><span class=identifier>add - </span><span class=special>(</span><span class=string>&quot;one&quot;</span><span class=special>, &amp;</span><span class=identifier>one</span><span class=special>) - </span><span class=special>(</span><span class=string>&quot;two&quot;</span><span class=special>, &amp;</span><span class=identifier>two</span><span class=special>)
-    </span><span class=special>;
-
- </span><span class=identifier>line </span><span class=special>= </span><span class=identifier>continuations</span><span class=special>[</span><span class=identifier>set_rest</span><span class=special>&lt;</span><span class=identifier>rule_t</span><span class=special>&gt;(</span><span class=identifier>rest</span><span class=special>)] </span><span class=special>&gt;&gt; </span><span class=identifier>rest</span><span class=special>;</span></pre> -<p>where continuations is a <a href="symbols.html">symbol table</a> with pointer to rule_t slots. one, two, name, line and rest are rules:</p> -<pre><span class=special> </span><span class=identifier>rule_t </span><span class=identifier>name</span><span class=special>; - </span><span class=identifier>rule_t </span><span class=identifier>line</span><span class=special>; - </span><span class=identifier>rule_t </span><span class=identifier>rest</span><span class=special>; - </span><span class=identifier>rule_t </span><span class=identifier>one</span><span class=special>; - </span><span class=identifier>rule_t </span><span class=identifier>two</span><span class=special>;
-
- </span><span class=identifier>symbols</span><span class=special>&lt;</span><span class=identifier>rule_t</span><span class=special>*&gt; </span><span class=identifier>continuations</span><span class=special>;</span></pre>
-<p>set_rest, the semantic action attached to continuations is:</p>
-<pre><span class=special> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>Rule</span><span class=special>&gt; - </span><span class=keyword>struct </span><span class=identifier>set_rest
-    </span><span class=special>{
- </span><span class=identifier>set_rest</span><span class=special>(</span><span class=identifier>Rule</span><span class=special>&amp; </span><span class=identifier>the_rule</span><span class=special>) - </span><span class=special>: </span><span class=identifier>the_rule</span><span class=special>(</span><span class=identifier>the_rule</span><span class=special>) </span><span class=special>{}
-
- </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>Rule</span><span class=special>* </span><span class=identifier>newRule</span><span class=special>) </span><span class=keyword>const - </span><span class=special>{ </span><span class=identifier>m_theRule </span><span class=special>= </span><span class=special>*</span><span class=identifier>newRule</span><span class=special>; </span><span class=special>}
-
- </span><span class=identifier>Rule</span><span class=special>&amp; </span><span class=identifier>the_rule</span><span class=special>;
-    </span><span class=special>};</span></pre>
-<p>Notice how the rest <tt>rule</tt> gets set dynamically when the set_rule action is called. The dynamic grammar parses inputs such as:</p>
-<p> &quot;one only&quot;<br>
-&quot;one again&quot;<br>
-&quot;two first, second&quot;</p>
-<p>The cool part is that the <tt>rest</tt> rule is set (by the <tt>set_rest</tt> action) depending on what the symbol table got. If it got a <em>&quot;one&quot;</em> then rest = one. If it got <em>&quot;two&quot;</em>, then rest = two. Very nifty! This technique should be very fast, especially when there are lots of keywords. It would be nice to add special facilities to make this easy to use. I imagine:</p> -<pre><span class=special> </span><span class=identifier>r </span><span class=special>= </span><span class=identifier>keywords </span><span class=special>&gt;&gt; </span><span class=identifier>rest</span><span class=special>;</span></pre> -<p>where <tt>keywords</tt> is a special parser (based on the symbol table) that automatically sets its RHS (rest) depending on the acquired symbol. This, I think, is mighty cool! Someday perhaps... </p> -<p><img src="theme/note.gif" width="16" height="16"> Also, see the <a href="switch_parser.html">switch parser</a> for another deterministic parsing trick for character/token prefixes. </p>
-<span class=special></span>
+<p>This technique, I'll call the <strong><em>"Nabialek trick" </em></strong>(from
+the name of its inventor, Sam Nabialek), can improve the rule dispatch
+from linear non-deterministic to deterministic. The trick applies to
+grammars where a keyword (operator, etc), precedes a production. There
+are lots of grammars similar to this:<br>这个技术我称之为 <strong><em>"Nabialek诀窍" </em></strong>(来自它的发明者 Sam Nabialek),可以 将规则的分派由线性非确定性改进为确定性的。该诀窍适用于关键字(操作符等)语 法,生成一个结果。有许多语法类似于:</p> +<pre> <span class="identifier">r </span><span class="special">=<br> </span><span class="identifier">keyword1 </span><span class="special">&gt;&gt; </span><span class="identifier">production1<br> </span><span class="special">| </span><span class="identifier">keyword2 </span><span class="special">&gt;&gt; </span><span class="identifier">production2<br> </span><span class="special">| </span><span class="identifier">keyword3 </span><span class="special">&gt;&gt; </span><span class="identifier">production3<br> </span><span class="special">| </span><span class="identifier">keyword4 </span><span class="special">&gt;&gt; </span><span class="identifier">production4<br> </span><span class="special">| </span><span class="identifier">keyword5 </span><span class="special">&gt;&gt; </span><span class="identifier">production5<br> </span><span class="comment">/*** etc ***/<br> </span><span class="special">;</span></pre>
+<p>The cascaded alternatives are tried one at a time through trial and
+error until something matches. The Nabialek trick takes advantage of
+the <a href="symbols.html">symbol table</a>'s search properties to optimize the dispatching of the alternatives. For an example, see <a href="../example/techniques/nabialek.cpp">nabialek.cpp</a>. The grammar works as follows. There are two rules (<tt>one</tt> and <tt>two</tt>). When "one" is recognized, rule <tt>one</tt> is invoked. When "two" is recognized, rule <tt>two</tt> is invoked. Here's the grammar:<br>这个级联 的多选是通过反复的试错,直至有某个选项匹配。Nabialek诀窍利用 <a href="symbols.html">符号表</a> 的查找特性来优化多个选项的分派。相关例子请见 <a href="../example/techniques/nabialek.cpp">nabialek.cpp</a>. 该语法工作如 下。有两个规则(<tt>one</tt> 和 <tt>two</tt>)。当识别出 "one" 时,调用规则 <tt>one</tt>。当识别出 "two" 时,则调用规则 <tt>two</tt>。语法如下:</p> +<pre><span class="special"> </span><span class="identifier">one </span><span class="special">= </span><span class="identifier">name</span><span class="special">;<br> </span><span class="identifier">two </span><span class="special">= </span><span class="identifier">name </span><span class="special">&gt;&gt; </span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">name</span><span class="special">;<br> <br> </span><span class="identifier">continuations</span><span class="special">.</span><span class="identifier">add<br> </span><span class="special">(</span><span class="string">"one"</span><span class="special">, &amp;</span><span class="identifier">one</span><span class="special">)<br> </span><span class="special">(</span><span class="string">"two"</span><span class="special">, &amp;</span><span class="identifier">two</span><span class="special">)<br> </span><span class="special">;<br> <br> </span><span class="identifier">line </span><span class="special">= </span><span class="identifier">continuations</span><span class="special">[</span><span class="identifier">set_rest</span><span class="special">&lt;</span><span class="identifier">rule_t</span><span class="special">&gt;(</span><span class="identifier">rest</span><span class="special">)] </span><span class="special">&gt;&gt; </span><span class="identifier">rest</span><span class="special">;</span></pre> +<p>where continuations is a <a href="symbols.html">symbol table</a> with pointer to rule_t slots. one, two, name, line and rest are rules:<br>其中 continuations 是一个 <a href="symbols.html">符号表</a>,带有指向 rule_t 项 的指针。one, two, name, line 和 rest 均为规则:</p> +<pre><span class="special"> </span><span class="identifier">rule_t </span><span class="identifier">name</span><span class="special">;<br> </span><span class="identifier">rule_t </span><span class="identifier">line</span><span class="special">;<br> </span><span class="identifier">rule_t </span><span class="identifier">rest</span><span class="special">;<br> </span><span class="identifier">rule_t </span><span class="identifier">one</span><span class="special">;<br> </span><span class="identifier">rule_t </span><span class="identifier">two</span><span class="special">;<br> <br> </span><span class="identifier">symbols</span><span class="special">&lt;</span><span class="identifier">rule_t</span><span class="special">*&gt; </span><span class="identifier">continuations</span><span class="special">;</span></pre> +<p>set_rest, the semantic action attached to continuations is:<br>set_rest 是附加至 continuations 的语义动作,如下:</p> +<pre><span class="special"> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">Rule</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">set_rest<br> </span><span class="special">{<br> </span><span class="identifier">set_rest</span><span class="special">(</span><span class="identifier">Rule</span><span class="special">&amp; </span><span class="identifier">the_rule</span><span class="special">)<br> </span><span class="special">: </span><span class="identifier">the_rule</span><span class="special">(</span><span class="identifier">the_rule</span><span class="special">) </span><span class="special">{}<br><br> </span><span class="keyword">void </span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">Rule</span><span class="special">* </span><span class="identifier">newRule</span><span class="special">) </span><span class="keyword">const<br> </span><span class="special">{ </span><span class="identifier">m_theRule </span><span class="special">= </span><span class="special">*</span><span class="identifier">newRule</span><span class="special">; </span><span class="special">}<br><br> </span><span class="identifier">Rule</span><span class="special">&amp; </span><span class="identifier">the_rule</span><span class="special">;<br> </span><span class="special">};</span></pre> +<p>Notice how the rest <tt>rule</tt> gets set dynamically when the set_rule action is called. The dynamic grammar parses inputs such as:<br>注 意,在 set_rule 动作被调用时,rest <tt>rule</tt> 是如何被动态设置。该动态语 法分析如下的输入:</p>
+<p> "one only"<br>
+"one again"<br>
+"two first, second"</p>
+<p>The cool part is that the <tt>rest</tt> rule is set (by the <tt>set_rest</tt> action) depending on what the symbol table got. If it got a <em>"one"</em> then rest = one. If it got <em>"two"</em>,
+then rest = two. Very nifty! This technique should be very fast,
+especially when there are lots of keywords. It would be nice to add
+special facilities to make this easy to use. I imagine:<br>最酷的部分 是,<tt>rest</tt> 规则被依据所获得的符号表而设置(通过 <tt>set_rest</tt> 动作 )。如果它获得一个 <em>"one"</em> 则 rest = one。如果它获得 <em>"two"</em>, +则 rest = two。1多漂亮!这种技术应该非常快,尤其是有大量关键字的时候。应该 增加一些特殊的工具令之更为易用。我想:</p> +<pre><span class="special"> </span><span class="identifier">r </span><span class="special">= </span><span class="identifier">keywords </span><span class="special">&gt;&gt; </span><span class="identifier">rest</span><span class="special">;</span></pre>
+<p>where <tt>keywords</tt> is a special parser (based on the symbol
+table) that automatically sets its RHS (rest) depending on the acquired
+symbol. This, I think, is mighty cool! Someday perhaps...<br>其中 <tt>keywords</tt> 是一个特殊的分析器(基于符号符),它自动根据所获得的符号设置 其右操作数(rest)。我想,这真的很酷!也许有一天... </p> +<p><img src="theme/note.gif" height="16" width="16"> Also, see the <a href="switch_parser.html">switch parser</a> for another deterministic parsing trick for character/token prefixes.<br><img src="theme/note.gif" height="16" width="16"> 另外,还有一个用于字符/记号前缀的确定性分析技巧,请 见 <a href="switch_parser.html">跳转分析器</a>。 </p>
+<span class="special"></span>
 <table border="0">
-  <tr>
+  <tbody><tr>
     <td width="10"></td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="style_guide.html"><img src="theme/l_arr.gif" border="0"></a></td> <td width="30"><a href="faq.html"><img src="theme/r_arr.gif" border="0"></a></td>
   </tr>
-</table>
+</tbody></table>
 <br>
 <hr size="1">
-<p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
+<p class="copyright">Copyright © 1998-2003 Joel de Guzman<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     http://www.boost.org/LICENSE_1_0.txt)</font></p>
 <p class="copyright">&nbsp;</p>
-</body>
-</html>
+</body></html>
=======================================
--- /trunk/libs/spirit/classic/doc/trees.html   Tue Mar 31 01:07:16 2009
+++ /trunk/libs/spirit/classic/doc/trees.html   Mon Oct 12 20:27:43 2009
@@ -1,16 +1,17 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>Trees</title>
-
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head><title>Trees</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <link rel="stylesheet" href="theme/style.css" type="text/css"></head>
 <body>
-<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
+<table background="theme/bkd2.gif" border="0" cellspacing="2" width="100%">
   <tbody><tr>
     <td width="10">
     <br>
 </td>
- <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Trees</b></font> + <td width="85%"> <font face="Verdana, Arial, Helvetica, sans-serif" size="6"><b>Trees 树</b></font>
     </td>
- <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> + <td width="112"><a href="http://spirit.sf.net";><img src="theme/spirit.gif" align="right" border="0" height="48" width="112"></a></td>
   </tr>
 </tbody></table>
 <br>
@@ -23,23 +24,23 @@
<td width="30"><a href="multi_pass.html"><img src="theme/r_arr.gif" border="0"></a></td>
    </tr>
 </tbody></table>
-<h2>Why use parse trees</h2>
+<h2>Why use parse trees 为什么要用分析树</h2>
<p> Parse trees are an in-memory representation of the input with a structure
-  that conforms to the grammar.</p>
-<p> The advantages of using parse trees instead of semantic actions:</p>
+ that conforms to the grammar.<br>分析树是输入在内存中的一个表示法,它带有 与语法相符合的结构。</p> +<p> The advantages of using parse trees instead of semantic actions:<br>使 用分析树替代语义动作的优点:</p>
 <ul>
<li>You can make multiple passes over the data without having to re-parse the
-    input.</li>
-  <li>You can perform transformations on the tree.</li>
+    input.<br>你可以多次遍历数据,而无需对输入进行重新分析。</li>
+ <li>You can perform transformations on the tree.<br>你可以在树上执行变 换。</li> <li>You can evaluate things in any order you want, whereas with attribute schemes
-    you have to process in a begin to end fashion.</li>
+ you have to process in a begin to end fashion.<br>你可以按任意顺序对你 想要的东西求值,而使用属性机制则你必须从头到尾来处理。</li> <li>You do not have to worry about backtracking and action side effects that
-    may occur with an ambiguous grammar.</li>
+ may occur with an ambiguous grammar.<br>你不需要担心一个模糊语法可能的 回溯和动作的副作用。</li>
 </ul>
-<p> <b>Example</b></p>
+<p> <b>Example 例子</b></p>
<p> Now that you think you may want to use trees, I'll give an example of how to use them and you can see how easy they are to use. So, following with tradition - (and the rest of the documentation) we'll do a calculator. Here's the grammar:</p> + (and the rest of the documentation) we'll do a calculator. Here's the grammar:<br>现在假设你想使用分析树,我将给出一个关于如何使用它们的例子,你会 看到使用它们是多容易。嗯,根据传统(以及本文档的其余部分),我们要实现一个计算 器。以下是语法:</p> <pre> <code><span class="identifier">integer </span><span class="special"> = </span><span class="identifier"><font color="#ff0000"><b>token_node_d</b></font></span><span class="special">[ (!</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'-'</span><span class="special">) &gt;&gt; +</span><span class="identifier">digit_p</span><span class="special">) ]<br> ;<br><br> </span><span class="identifier">factor<br> </span><span class="special">= </span><span class="identifier">integer<br> </span><span class="special">| </span><span class="literal">'(' </span><span class="special">&gt;&gt; </span><span class="identifier">expression </span><span class="special">&gt;&gt; </span><span class="literal">')'<br> </span><span class="special">| (</span><span class="literal">'-' </span><span class="special">&gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> ;<br><br> </span><span class="identifier">term<br> </span><span class="special">= </span><span class="identifier">factor </span><span class="special"> &gt;&gt; *( (</span><span class="literal">'*' </span><span class="special">&gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> | (</span><span class="literal">'/' </span><span class="special">&gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> )<br> ;<br><br> </span><span class="identifier">expression<br> </span><span class="special">= </span><span class="identifier">term<br> </span><span class="special">&gt;&gt; *( (</span><span class="literal">'+' </span><span class="special">&gt;&gt; </span><span class="identifier">term</span><span class="special">)<br> | (</span><span class="literal">'-' </span><span class="special">&gt;&gt; </span><span class="identifier">term</span><span class="special">)<br> )<br> ;</span></code></pre>
@@ -49,28 +50,30 @@
   Further note that <tt>token_node_d</tt> is an implicit lexeme (that means
   no <tt>lexeme_d</tt> is needed to switch to character level parsing).
   As you'll soon see, it's easier to convert the input into an int when all
- the characters are in one node. Here is how the parse is done to create a tree:</p> + the characters are in one node. Here is how the parse is done to create a tree:<br>现在,你会留意到,在这个语法中不同的仅仅是 <tt>token_node_d</tt> + 指示符。它导致这个 integer 规则在一个节点处结束。没有 <tt>token_node_d</tt>,则每个字符都会有自己的节点。进一步,留意 <tt>token_node_d</tt> 是一个隐式的词位(这意味着,不需要 <tt>lexeme_d</tt> 来 切换至字符层面的分析)。正如你即将看到的,如果所有字符在一个节点中,则更容易 将输入转换为一个 int。以下是如何在分析完成后创建一棵树:</p> <pre> <code><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt; </span><span class="identifier">info </span><span class="special">= </span><span class="identifier"><font color="#ff0000"><b>pt_parse</b></font></span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">expression</span><span class="special">);</span></code></pre> <p> <tt>pt_parse()</tt> is similar to <tt>parse()</tt>. There are four overloads: two for pairs of first and last iterators and two for character strings. Two
-  of the functions take a skipper parser and the other two do not.</p>
+ of the functions take a skipper parser and the other two do not.<br><tt>pt_parse()</tt> 类似于 <tt>parse()</tt>。它有四个重载:两个使用 first 和 last 迭代器对,两个使用字符串。两个接受一个跳过分析器,另两个则不接 受。</p> <p> The <tt>tree_parse_info</tt> struct contains the same information as a <tt>parse_info</tt> struct as well as one extra data member called trees. When the parse finishes,
-  trees will contain the parse tree.</p>
-<p> Here is how you can use the tree to evaluate the input:</p>
+ trees will contain the parse tree.<br>结构&nbsp;<tt>tree_parse_info</tt> 包含与 <tt>parse_info</tt> + 结构相同的信息,以及一个额外的数据成员,名为 trees。当分析完成时,trees 中将包含该分析树。</p> +<p> Here is how you can use the tree to evaluate the input:<br>以下是如何使 用这棵树来对输入求值:</p> <pre> <code><span class="keyword">if </span><span class="special">(</span><span class="identifier">info</span><span class="special">.</span><span class="identifier">full</span><span class="special">)<br> {<br> </span><span class="identifier">cout </span><span class="special">&lt;&lt; </span><span class="string">"parsing succeeded\n"</span><span class="special">;<br> </span><span class="identifier">cout </span><span class="special">&lt;&lt; </span><span class="string">"result = " </span><span class="special">&lt;&lt; </span><span class="identifier"><font color="#ff0000"><b>evaluate</b></font></span><span class="special">(</span><span class="identifier">info</span><span class="special">) &lt;&lt; </span><span class="string">"\n\n"</span><span class="special">;<br> }</span></code></pre> <p> Now you ask, where did <tt>evaluate()</tt> come from? Is it part of spirit? Unfortunately, no, <tt>evaluate()</tt> is only a part of the sample. Here it
-  is:</p>
+ is:<br>现在你会问,<tt>evaluate()</tt> 是从哪来的?它是spirit的一部分 吗?很不幸,它不是,<tt>evaluate()</tt> 只是本例的一部分。以下就是它:</p> <pre> <code><span class="keyword">long </span><span class="identifier">evaluate</span><span class="special">(</span><span class="keyword">const </span><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt;&amp; </span><span class="identifier">info</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">info</span><span class="special">.</span><span class="identifier">trees</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> </span><span class="special">}</span></code></pre> <p> So here you see evaluate() simply calls <tt>eval_expression()</tt> passing - the begin() iterator of info.trees. Now here's the rest of the example:</p> -<pre> <code><span class="comment">// Here's some typedefs to simplify things<br> </span><span class="keyword">typedef char const</span><span class="special">* </span><span class="identifier">iterator_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">&gt; </span><span class="identifier"> parse_tree_match_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">parse_tree_match_t</span><span class="special">::</span><span class="identifier">const_tree_iterator iter_t</span><span class="special">;<br><br> </span><span class="comment">// Here's the function prototypes that we'll use. One function for each<br> // grammar rule</span><span class="special">.<br> </span><span class="keyword">long </span><span class="identifier">evaluate</span><span class="special">(</span><span class="keyword">const </span><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt;&amp; </span><span class="identifier">info</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_factor</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_integer</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br><br> </span><span class="comment">// i should be pointing to a node created by the expression rule<br> </span><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// first child points to a term, so call eval_term on it<br> </span><span class="identifier">iter_t chi </span><span class="special">= </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();<br> </span><span class="keyword">long </span><span class="identifier">lhs </span><span class="special">= </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">chi</span><span class="special">);<br> </span><span class="keyword">for </span><span class="special">(++</span><span class="identifier">chi</span><span class="special">; </span><span class="identifier">chi </span><span class="special">!= </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">end</span><span class="special">(); ++</span><span class="identifier">chi</span><span class="special">)<br> {<br> </span><span class="comment">// next node points to the operator. The text of the operator is<br> // stored in value (a vector&lt;char&gt;)<br> </span><span class="keyword">char </span><span class="identifier">op </span><span class="special">= *(</span><span class="identifier">chi</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> ++</span><span class="identifier">chi</span><span class="special">;<br> </span><span class="keyword">long </span><span class="identifier">rhs </span><span class="special">= </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">chi</span><span class="special">);<br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">op </span><span class="special">== </span><span class="literal">'+'</span><span class="special">)<br> </span><span class="identifier">lhs </span><span class="special">+= </span><span class="identifier">rhs</span><span class="special">;<br> </span><span class="keyword">else if </span><span class="special">(</span><span class="identifier">op </span><span class="special">== </span><span class="literal">'-'</span><span class="special">)<br> </span><span class="identifier">lhs </span><span class="special">-= </span><span class="identifier">rhs</span><span class="special">;<br> </span><span class="keyword">else<br> </span><span class="identifier">assert</span><span class="special">(</span><span class="number">0</span><span class="special">);<br> }<br> </span><span class="keyword">return </span><span class="identifier">lhs</span><span class="special">;<br> }<br><br> </span><span class="keyword">long </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// ... see <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a> for complete example<br> // (it's rather similar to eval_expression() ) ...<br> </span><span class="special">}<br><br> </span><span class="keyword">long </span><span class="identifier">eval_factor</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// ... again, see <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a> if you want all the details ...<br> </span><span class="special">}<br><br> </span><span class="keyword">long </span><span class="identifier">eval_integer</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// use the range constructor for a string<br> </span><span class="identifier">string </span><span class="identifier">integer</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(), </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">end</span><span class="special">());<br> </span><span class="comment">// convert the string to an integer<br> </span><span class="keyword">return </span><span class="identifier">strtol</span><span class="special">(</span><span class="identifier">integer</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">(), </span><span class="number">0</span><span class="special">, </span><span class="number">10</span><span class="special">);<br> </span><span class="special">}<br></span></code></pre> -<p> <img height="16" width="15" src="theme/lens.gif"> The full source code can be <a href="../example/fundamental/parse_tree_calc1.cpp">viewed here</a>. This is part of the Spirit distribution.</p> -<p>So, you like what you see, but maybe you think that the parse tree is too + the begin() iterator of info.trees. Now here's the rest of the example:<br>你可以看到 evaluate() 只是调用 <tt>eval_expression()</tt> 而 已,传入&nbsp;info.trees 的 begin() 迭代器。以下是该例子的其它部分:</p> +<pre> <code><span class="comment">// Here's some typedefs to simplify things 这是一些typedef,用于简化<br> </span><span class="keyword">typedef char const</span><span class="special">* </span><span class="identifier">iterator_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">&gt; </span><span class="identifier"> parse_tree_match_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">parse_tree_match_t</span><span class="special">::</span><span class="identifier">const_tree_iterator iter_t</span><span class="special">;<br><br> </span><span class="comment">// Here's the function prototypes that we'll use. One function for each<br> // grammar rule</span><span class="special">. <span style="font-style: italic;">这是要用的函数原型。每个语法规则一个函数。 </span><br> </span><span class="keyword">long </span><span class="identifier">evaluate</span><span class="special">(</span><span class="keyword">const </span><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt;&amp; </span><span class="identifier">info</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_factor</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br> </span><span class="keyword">long </span><span class="identifier">eval_integer</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">);<br><br> </span><span class="comment">// i should be pointing to a node created by the expression rule<br> // i 应指向一个由 expression规则创建的节点<br> </span><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// first child points to a term, so call eval_term on it 第一个子节点指向一个term,因此对它调用eval_term<br> </span><span class="identifier">iter_t chi </span><span class="special">= </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();<br> </span><span class="keyword">long </span><span class="identifier">lhs </span><span class="special">= </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">chi</span><span class="special">);<br> </span><span class="keyword">for </span><span class="special">(++</span><span class="identifier">chi</span><span class="special">; </span><span class="identifier">chi </span><span class="special">!= </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">end</span><span class="special">(); ++</span><span class="identifier">chi</span><span class="special">)<br> {<br> </span><span class="comment">// next node points to the operator. The text of the operator is<br> // stored in value (a vector&lt;char&gt;) 下一个 节点指向操作符。操作符的文本保存在vector&lt;char&gt;中<br> </span><span class="keyword">char </span><span class="identifier">op </span><span class="special">= *(</span><span class="identifier">chi</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> ++</span><span class="identifier">chi</span><span class="special">;<br> </span><span class="keyword">long </span><span class="identifier">rhs </span><span class="special">= </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">chi</span><span class="special">);<br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">op </span><span class="special">== </span><span class="literal">'+'</span><span class="special">)<br> </span><span class="identifier">lhs </span><span class="special">+= </span><span class="identifier">rhs</span><span class="special">;<br> </span><span class="keyword">else if </span><span class="special">(</span><span class="identifier">op </span><span class="special">== </span><span class="literal">'-'</span><span class="special">)<br> </span><span class="identifier">lhs </span><span class="special">-= </span><span class="identifier">rhs</span><span class="special">;<br> </span><span class="keyword">else<br> </span><span class="identifier">assert</span><span class="special">(</span><span class="number">0</span><span class="special">);<br> }<br> </span><span class="keyword">return </span><span class="identifier">lhs</span><span class="special">;<br> }<br><br> </span><span class="keyword">long </span><span class="identifier">eval_term</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// ... see <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a> for complete example<br> // (it's rather similar to eval_expression() ) ...<br></span></code><code><span class="special"> </span><span class="comment">// ... 完整的例子见 <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a>, (与eval_expression()相似)<br></span></code><code><span class="comment"> </span><span class="special">}<br><br> </span><span class="keyword">long </span><span class="identifier">eval_factor</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> {<br> </span><span class="comment">// ... again, see <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a> if you want all the details ...<br> // ... 同样,如果想知道细节,请 见</span></code><code><span class="comment"> <a href="../example/fundamental/parse_tree_calc1.cpp">parse_tree_calc1.cpp</a> </span></code><code><span class="comment"> <br> </span><span class="special">}<br><br> </span><span class="keyword">long </span><span class="identifier">eval_integer</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// use the range constructor for a string 对字 符串使用区间构造器<br> </span><span class="identifier">string </span><span class="identifier">integer</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(), </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">end</span><span class="special">());<br> </span><span class="comment">// convert the string to an integer 将字符串转换为整数<br> </span><span class="keyword">return </span><span class="identifier">strtol</span><span class="special">(</span><span class="identifier">integer</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">(), </span><span class="number">0</span><span class="special">, </span><span class="number">10</span><span class="special">);<br> </span><span class="special">}<br></span></code></pre>
+
+<p> <img src="theme/lens.gif" height="16" width="15"> The full source code can be <a href="../example/fundamental/parse_tree_calc1.cpp">viewed here</a>. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 完整的源代码可以 <a href="../example/fundamental/parse_tree_calc1.cpp">在此查看</a>。这是 Spirit发布包的一部分。</p><p>So, you like what you see, but maybe you think that the parse tree is too hard to process? With a few more directives you can generate an abstract syntax tree (ast) and cut the amount of evaluation code by at least <b>50%</b>. So
-    without any delay, here's the ast calculator grammar:</p>
+ without any delay, here's the ast calculator grammar:<br>就象你所看到 的,也许你认为这个分析树很难处理?只要一点点指示符,你就可以生成一个抽象语法 树(ast)并缩减至少<b>50%</b>的求值代码数量。因此,不要拖延了,以下就是这个 ast 计算器语法:</p> <pre> <code><span class="identifier">integer<br> </span><span class="special">= </span><span class="identifier"><font color="#ff0000"><b>leaf_node_d</b></font></span><span class="special">[ </span><span class="special">(!</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'-'</span><span class="special">) &gt;&gt; +</span><span class="identifier">digit_p</span><span class="special">) ]<br> ;<br><br> </span><span class="identifier">factor<br> </span><span class="special">= </span><span class="identifier">integer<br> </span><span class="special">| </span><span class="identifier"><font color="#ff0000"><b>inner_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'('</span><span class="special">) &gt;&gt; </span><span class="identifier">expression </span><span class="special">&gt;&gt; </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">')'</span><span class="special">)]<br> | (</span><span class="identifier"><font color="#ff0000"><b>root_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'-'</span><span class="special">)] &gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> ;<br><br> </span><span class="identifier">term<br> </span><span class="special">= </span><span class="identifier">factor </span><span class="special"> &gt;&gt; *( (</span><span class="identifier"><font color="#ff0000"><b>root_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'*'</span><span class="special">)] &gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> | (</span><span class="identifier"><font color="#ff0000"><b>root_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'/'</span><span class="special">)] &gt;&gt; </span><span class="identifier">factor</span><span class="special">)<br> )<br> ;<br><br> </span><span class="identifier">expression<br> </span><span class="special">= </span><span class="identifier">term<br> </span><span class="special">&gt;&gt; *( (</span><span class="identifier"><font color="#ff0000"><b>root_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'+'</span><span class="special">)] &gt;&gt; </span><span class="identifier">term</span><span class="special">)<br> | (</span><span class="identifier"><font color="#ff0000"><b>root_node_d</b></font></span><span class="special">[</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'-'</span><span class="special">)] &gt;&gt; </span><span class="identifier">term</span><span class="special">)<br> )<br> ;</span></code></pre> <p> The differences from the parse tree grammar are hi-lighted in <b><font color="#ff0000">bold-red</font></b>.
@@ -79,34 +82,32 @@
parentheses when evaluating the expression. The <tt>root_node_d</tt> directive is the key to ast generation. A node that is generated by the parser inside of <tt>root_node_d</tt> is marked as a root node. When a root node is created, - it becomes a root or parent node of the other nodes generated by the same rule.</p> + it becomes a root or parent node of the other nodes generated by the same rule.<br>与分析树语法的差异用 <b><font color="#ff0000">bold-red</font></b> 高亮显示。指示符 <tt>inner_node_d</tt> 令内层分析器生成的第一个和最后一个节点被忽略,因为我们在对表达式求值时不关心 其括号。指示符 <tt>root_node_d</tt> 是生成 ast 的关键。由 <tt>root_node_d</tt>&nbsp;内部的分析器所生成的节点被标记为根节点。当一个根节 点被创建时,它会成为同一个规则所生成的其它节点的根节点或父节点。</p> <p> To start the parse and generate the ast, you must use the ast_parse functions,
-  which are similar to the pt_parse functions.</p>
+ which are similar to the pt_parse functions.<br>要开始分析和生成 ast,你 必须使用 ast_parse 函数,它类似于 pt_parse 函数。</p> <pre> <code><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt; </span><span class="identifier">info </span><span class="special">= </span><span class="identifier">ast_parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">expression</span><span class="special">);</span></code></pre> <p> Here is the eval_expression function (note that to process the ast we only
-  need one function instead of four):</p>
-<pre> <code><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">integer</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="comment">// convert string to integer<br> </span><span class="identifier">string </span><span class="identifier">integer</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(), </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">end</span><span class="special">());<br> </span><span class="keyword">return </span><span class="identifier">strtol</span><span class="special">(</span><span class="identifier">integer</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">(), </span><span class="number">0</span><span class="special">, </span><span class="number">10</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">factor</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="comment">// factor can only be unary minus<br> </span><span class="keyword">return </span><span class="special">- </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">term</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'*'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">*<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'/'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">/<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">expression</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'+'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">+<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'-'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">-<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="special">}<br><br> </span><span class="keyword">return </span><span class="number">0</span><span class="special">;<br> </span><span class="special">}<br></span></code></pre> -<p> <img src="theme/lens.gif" width="15" height="16"> An entire working example is <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a>. Hopefully this example has been enough to whet your appetite for - trees. For more nitty-gritty details, keep on reading the rest of this chapter.</p> + need one function instead of four):<br>以下是 eval_expression 函数(注 意,处理 ast 我们只需要一个函数,而不是四个):</p> +<pre> <code><span class="keyword">long </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">iter_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">i</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">integer</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="comment">// convert string to integer 将字符串转换为整数 <br> </span><span class="identifier">string </span><span class="identifier">integer</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(), </span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">end</span><span class="special">());<br> </span><span class="keyword">return </span><span class="identifier">strtol</span><span class="special">(</span><span class="identifier">integer</span><span class="special">.</span><span class="identifier">c_str</span><span class="special">(), </span><span class="number">0</span><span class="special">, </span><span class="number">10</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">factor</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="comment">// factor can only be unary minus factor只能 是单参减法<br> </span><span class="keyword">return </span><span class="special">- </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">term</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'*'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">*<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'/'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">/<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">id</span><span class="special">() </span><span class="special">== </span><span class="identifier">parser_id</span><span class="special">(&amp;</span><span class="identifier">expression</span><span class="special">))<br> </span><span class="special">{<br> </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'+'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">+<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="keyword">else </span><span class="keyword">if </span><span class="special">(*</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">value</span><span class="special">.</span><span class="identifier">begin</span><span class="special">() </span><span class="special">== </span><span class="literal">'-'</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="keyword">return </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()) </span><span class="special">-<br> </span><span class="identifier">eval_expression</span><span class="special">(</span><span class="identifier">i</span><span class="special">-&gt;</span><span class="identifier">children</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()+</span><span class="number">1</span><span class="special">);<br> </span><span class="special">}<br> </span><span class="special">}<br><br> </span><span class="keyword">return </span><span class="number">0</span><span class="special">;<br> </span><span class="special">}<br></span></code></pre> +<p> <img src="theme/lens.gif" height="16" width="15"> An entire working example is <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a>. Hopefully this example has been enough to whet your appetite for + trees. For more nitty-gritty details, keep on reading the rest of this chapter.<br><img src="theme/lens.gif" height="16" width="15"> 整个可用的例子 在 <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a>。希望该例 子足以满足你对分析树的欲望。更具体的细节,请继续阅读本章剩余部分。</p>
 <a name="usage"></a>
-<h2>Usage</h2>
+<h2>Usage 用法</h2>
 <a name="pt_parse"></a>
 <h3>pt_parse</h3>
-<p> To create a parse tree, you can call one of the five free functions:</p> -<pre> <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>FactoryT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>, </span><span class=identifier>FactoryT</span><span class=special>&gt; <br> </span><span class=identifier>pt_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last_</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip_</span><span class=special>, - </span><span class="identifier">FactoryT</span><span class=special> </span><span class="keyword">const</span><span class=special> &amp; </span><span class="identifier">factory_</span><span class=special> = </span><span class="identifier">FactoryT</span><span class=special>()); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>&gt; <br> </span><span class=identifier>pt_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last_</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip_</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>&gt; <br> </span><span class=identifier>pt_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last_</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>*&gt; <br> </span><span class=identifier>pt_parse</span><span class=special>( <br> </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>*&gt; <br> </span><span class=identifier>pt_parse</span><span class=special>( <br> </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>);<br></span></pre> +<p> To create a parse tree, you can call one of the five free functions:<br>要创建一个分析树,你可以调用以下五个自由函数之一:</p> +<pre> <span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">FactoryT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">, </span><span class="identifier">FactoryT</span><span class="special">&gt; <br> </span><span class="identifier">pt_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last_</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip_</span><span class="special">,<br> </span><span class="identifier">FactoryT</span><span class="special"> </span><span class="keyword">const</span><span class="special"> &amp; </span><span class="identifier">factory_</span><span class="special"> = </span><span class="identifier">FactoryT</span><span class="special">()); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt; <br> </span><span class="identifier">pt_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last_</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip_</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt; <br> </span><span class="identifier">pt_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last_</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">*&gt; <br> </span><span class="identifier">pt_parse</span><span class="special">( <br> </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">str</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">*&gt; <br> </span><span class="identifier">pt_parse</span><span class="special">( <br> </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">str</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">);<br></span></pre>
 <a name="ast_parse"></a>
 <h3>ast_parse</h3>
<p> To create an abstract syntax tree (ast for short) you call one of the five
-  free functions:</p>
-<pre> <span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>FactoryT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>, </span><span class=identifier>FactoryT</span><span class=special>&gt; <br> </span><span class=identifier>ast_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last_</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip_</span><span class=special>, - </span><span class="identifier"> FactoryT</span><span class=special> </span><span class="keyword">const</span><span class=special> &amp; </span><span class="identifier">factory_</span><span class=special> = </span><span class="identifier">FactoryT</span><span class=special>()</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>&gt; <br> </span><span class=identifier>ast_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last_</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip_</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>IteratorT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>IteratorT</span><span class=special>&gt; <br> </span><span class=identifier>ast_parse</span><span class=special>( <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>first_</span><span class=special>, <br> </span><span class=identifier>IteratorT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>last</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>SkipT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>*&gt; <br> </span><span class=identifier>ast_parse</span><span class=special>( <br> </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>, <br> </span><span class=identifier>SkipT </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>skip</span><span class=special>); <br> </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>CharT</span><span class=special>, </span><span class=keyword>typename </span><span class=identifier>ParserT</span><span class=special>&gt; <br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>*&gt; <br> </span><span class=identifier>ast_parse</span><span class=special>( <br> </span><span class=identifier>CharT </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>, <br> </span><span class=identifier>parser</span><span class=special>&lt;</span><span class=identifier>ParserT</span><span class=special>&gt; </span><span class=keyword>const</span><span class=special>&amp; </span><span class=identifier>parser</span><span class=special>);<br></span></pre> + free functions:<br>要创建一个抽象语法树(缩写为ast),你可以调用以下五个自 由函数之一:</p> +<pre> <span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">FactoryT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">, </span><span class="identifier">FactoryT</span><span class="special">&gt; <br> </span><span class="identifier">ast_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last_</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip_</span><span class="special">,<br> </span><span class="identifier"> FactoryT</span><span class="special"> </span><span class="keyword">const</span><span class="special"> &amp; </span><span class="identifier">factory_</span><span class="special"> = </span><span class="identifier">FactoryT</span><span class="special">()</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt; <br> </span><span class="identifier">ast_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last_</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip_</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt; <br> </span><span class="identifier">ast_parse</span><span class="special">( <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first_</span><span class="special">, <br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">SkipT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">*&gt; <br> </span><span class="identifier">ast_parse</span><span class="special">( <br> </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">str</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">, <br> </span><span class="identifier">SkipT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">skip</span><span class="special">); <br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">CharT</span><span class="special">, </span><span class="keyword">typename </span><span class="identifier">ParserT</span><span class="special">&gt; <br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">*&gt; <br> </span><span class="identifier">ast_parse</span><span class="special">( <br> </span><span class="identifier">CharT </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">str</span><span class="special">, <br> </span><span class="identifier">parser</span><span class="special">&lt;</span><span class="identifier">ParserT</span><span class="special">&gt; </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">parser</span><span class="special">);<br></span></pre>
 <a name="tree_parse_info"></a>
 <h3>tree_parse_info</h3>
<p> The <tt>tree_parse_info</tt> struct returned from pt_parse and ast_parse contains
-  information about the parse:</p>
+ information about the parse:<br>从 pt_parse 和 ast_parse 返回的 <tt>tree_parse_info</tt> 结构含有本次分析的信息:</p> <pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT </span><span class="special">= </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">*&gt;<br> </span><span class="keyword">struct </span><span class="identifier">tree_parse_info<br> </span><span class="special">{<br> </span><span class="identifier">IteratorT </span><span class="identifier">stop</span><span class="special">;<br> </span><span class="keyword">bool </span><span class="identifier">match</span><span class="special">;<br> </span><span class="keyword">bool </span><span class="identifier">full</span><span class="special">;<br> </span><span class="keyword">std::size_t </span><span class="identifier">length</span><span class="special">;<br><br> </span><span class="keyword">typename </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt;::</span><span class="identifier">container_t </span><span class="identifier">trees</span><span class="special">;<br> </span><span class="special">};<br></span></code></pre>
-<table width="90%" border="0" align="center">
+<table align="center" border="0" width="90%">
   <tbody><tr>
     <td class="table_title" colspan="10"> tree_parse_info </td>
   </tr>
@@ -114,23 +115,23 @@
   </tr><tr>
     <td class="table_cells"><b>stop</b></td>
<td class="table_cells">points to the final parse position (i.e. parsing processed
-      the input up to this point).</td>
+ the input up to this point).<br>指向最后的分析位置(即此点之前的输入已 完成分析)</td>
   </tr>
   <tr><td class="table_cells"><b>match</b></td>
<td class="table_cells">true if parsing is successful. This may be full (the parser consumed all the input), or partial (the parser consumed only a portion
-    of the input.)</td>
+ of the input.)<br>如果分析成功则为 true。可能是完整的(分析器消耗了所有 输入),或部分的(分析器只消耗了部分输入)。</td>
   </tr>
   <tr><td class="table_cells"><b>full</b></td>
<td class="table_cells">true when we have a full match (when the parser consumed
-    all the input).</td>
+    all the input).<br>完全匹配(分析器消耗了所有输入)时为 true。</td>
   </tr>
   <tr><td class="table_cells"><b>length</b></td>
<td class="table_cells">The number of characters consumed by the parser. This - is valid only if we have a successful match (either partial or full).</td> + is valid only if we have a successful match (either partial or full).<br>分析器所消耗的字符数量。仅当匹配成功(部分或全部)时有效。</td>
   </tr>
   <tr><td class="table_cells"><b>trees</b></td>
-  <td class="table_cells">Contains the root node(s) of the tree.</td>
+ <td class="table_cells">Contains the root node(s) of the tree.<br>包含树 的根节点。</td>
   </tr>
 </tbody></table>
 <a name="tree_match"></a>
@@ -138,54 +139,64 @@
<p> When Spirit is generating a tree, the parser's parse() member function will return a tree_match object, instead of a match object. tree_match has three template parameters. The first is the Iterator type which defaults to <tt>char - const*</tt>. The second is the node factory, which defaults to <a href="#node_val_data_factory">node_val_data_factory</a>. + const*</tt>. The second is the node factory, which defaults to <a href="trees.html#node_val_data_factory">node_val_data_factory</a>. The third is the attribute type stored in the match. A tree_match has a member - variable which is a container (a <tt>std::vector</tt>) of <a href="#tree_node">tree_node</a> + variable which is a container (a <tt>std::vector</tt>) of <a href="trees.html#tree_node">tree_node</a> objects named trees. For efficiency reasons, when a tree_match is copied, the trees are <b>not</b> copied, they are moved to the new object, and the source object is left with an empty tree container. tree_match supports the same interface as the match class: it has an operator bool() so you can test it for a sucessful match: if (matched), and you can query the match length via the length() function.
-  The class has this interface:</p>
+ The class has this interface:<br>当Spirit生成一棵树时,分析器的 parse() 成员函数将返回一个 tree_match 对象,而不是一个 match 对象。tree_match 有三个 模板参数。第一个是 Iterator 类型,缺省为 <tt>char + const*</tt>。第二个是节点工厂,缺省为 <a href="#node_val_data_factory">node_val_data_factory</a>。第三个是保存在匹配 中的属性类型。tree_match 有一个名为 trees 的成员变量,它是一个 <a href="#tree_node">tree_node</a>
+  容器(一个 <tt>std::vector</tt>)。
+由于效率原因,当一个 tree_match 被复制时,将不复制这个
+trees,而是把它移至新对象中,而源对象中则只留下一个空的树容器。tree_match 支持与 match 类相同的接口:它有一个 +operator bool(),因此你可以测试它是否一个成功的匹配:如果是(已匹配的),则你 可以通过 length()
+函数查询该匹配的长度。该类具有以下接口:</p>
<pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT </span><span class="special">= </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">*, </span><span class="keyword">typename </span><span class="identifier">NodeFactoryT </span><span class="special">= </span><span class="identifier">node_val_data_factory</span><span class="special">&lt;&gt; </span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">tree_match<br> </span><span class="special">{<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">NodeFactoryT</span><span class="special">::</span><span class="keyword">template </span><span class="identifier">factory</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt; </span><span class="identifier">node_factory_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">node_factory_t</span><span class="special">::</span><span class="identifier">node_t </span><span class="identifier">parse_node_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_node</span><span class="special">&lt;</span><span class="identifier">parse_node_t</span><span class="special">&gt; </span><span class="identifier">node_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">node_t</span><span class="special">::</span><span class="identifier">children_t </span><span class="identifier">container_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">iterator </span><span class="identifier">tree_iterator</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">const_iterator </span><span class="identifier">const_tree_iterator</span><span class="special">;<br><br> </span><span class="identifier">tree_match</span><span class="special">();<br> </span><span class="identifier">tree_match</span><span class="special">(</span><span class="keyword">std::size_t </span><span class="identifier">length</span><span class="special">, </span><span class="identifier">parse_node_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">n</span><span class="special">);<br> </span><span class="identifier">tree_match</span><span class="special">(</span><span class="identifier">tree_match </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="keyword">explicit </span><span class="identifier">tree_match</span><span class="special">(</span><span class="identifier">match </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="identifier">tree_match</span><span class="special">&amp; </span><span class="keyword">operator</span><span class="special">=(</span><span class="identifier">tree_match </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">tree_match</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="keyword">operator </span><span class="keyword">bool</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">int </span><span class="identifier">length</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br><br> </span><span class="identifier">container_t </span><span class="identifier">trees</span><span class="special">;<br> </span><span class="special">};</span></code></pre> <p> When a parse has sucessfully completed, the trees data member will contain
-  the root node of the tree. </p>
-<table width="80%" border="0" align="center">
+ the root node of the tree.<br>当一次分析成功完成,数据成员 trees 将包含树 的根节点。 </p>
+<table align="center" border="0" width="80%">
   <tbody><tr>
- <td class="note_box"><img src="theme/lens.gif" width="15" height="16"> <b>vector?</b><br> + <td class="note_box"><img src="theme/lens.gif" height="16" width="15"> <b>vector?</b><br>
       <br>
You may wonder, why is it a vector then? The answer is that it is partly for implementation purposes, and also if you do not use any rules in your grammar, then trees will contain a sequence of nodes that will not have
-      any children.</td>
+ any children.<br>你可能会奇怪,为什么要用vector?答案是,这部分是为了 实现的目的,而且如果你在你的语法中没有使用任何规则,那么 trees 将包含一系列 没有子节点的节点。</td>
   </tr>
 </tbody></table>
-<p> Having spirit create a tree is similar to how a normal parse is done:</p> -<pre> <code><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="identifier">hit </span><span class="special">= </span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">tree_scanner</span><span class="special">);<br><br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">hit</span><span class="special">)<br> </span><span class="identifier">process_tree_root</span><span class="special">(</span><span class="identifier">hit</span><span class="special">.</span><span class="identifier">trees</span><span class="special">[</span><span class="number">0</span><span class="special">]); </span><span class="comment">// do something with the tree</span></code></pre> +<p> Having spirit create a tree is similar to how a normal parse is done:<br>spirit 创建分析树类似于进行普通的分析:</p> +<pre> <code><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="identifier">hit </span><span class="special">= </span><span class="identifier">expression</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">tree_scanner</span><span class="special">);<br><br> </span><span class="keyword">if </span><span class="special">(</span><span class="identifier">hit</span><span class="special">)<br> </span><span class="identifier">process_tree_root</span><span class="special">(</span><span class="identifier">hit</span><span class="special">.</span><span class="identifier">trees</span><span class="special">[</span><span class="number">0</span><span class="special">]); </span><span class="comment">// do something with the tree 对分析树做操作</span></code></pre>
 <a name="tree_node"></a>
 <h3>tree_node</h3>
-<p> Once you have created a tree by calling <a href="#pt_parse">pt_parse</a> - or <a href="#ast_parse">ast_parse</a>, you have a <a href="#tree_parse_info">tree_parse_info</a> +<p> Once you have created a tree by calling <a href="trees.html#pt_parse">pt_parse</a> + or <a href="trees.html#ast_parse">ast_parse</a>, you have a <a href="trees.html#tree_parse_info">tree_parse_info</a> which contains the root node of the tree, and now you need to do something with - the tree. The data member trees of <a href="#tree_parse_info">tree_parse_info</a> + the tree. The data member trees of <a href="trees.html#tree_parse_info">tree_parse_info</a> is a std::vector&lt;tree_node&gt;. tree_node provides the tree structure. The class has one template parameter named T. tree_node contains an instance of type T. It also contains a std::vector&lt;tree_node&lt;T&gt; &gt; which are
-  the node's children. The class looks like this:</p>
+ the node's children. The class looks like this:<br>一旦你通过调用 <a href="#pt_parse">pt_parse</a> 或 <a href="#ast_parse">ast_parse</a> 创建了分 析树,你就有了一个 <a href="#tree_parse_info">tree_parse_info</a>,它包含了 树的根节点,而现在你需要对这棵树做一些操作。<a href="#tree_parse_info">tree_parse_info</a>
+的数据成员 tress 是一个 std::vector&lt;tree_node&gt;。tree_node
+提供了这个树结构。这个类有一个名为 T 的模板参数。tree_node 包含一个类型为 T 的实例。它还包含有一个 +std::vector&lt;tree_node&lt;T&gt; &gt; 作为该节点的子节点。该类看起来就 象:</p> <pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">T</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">tree_node<br> </span><span class="special">{<br> </span><span class="keyword">typedef </span><span class="identifier">T </span><span class="identifier">parse_node_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">tree_node</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt; </span><span class="special">&gt; </span><span class="identifier">children_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">children_t</span><span class="special">::</span><span class="identifier">iterator </span><span class="identifier">tree_iterator</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">children_t</span><span class="special">::</span><span class="identifier">const_iterator </span><span class="identifier">const_tree_iterator</span><span class="special">;<br><br> </span><span class="identifier">T </span><span class="identifier">value</span><span class="special">;<br> </span><span class="identifier">children_t </span><span class="identifier">children</span><span class="special">;<br><br> </span><span class="identifier">tree_node</span><span class="special">();<br> </span><span class="keyword">explicit </span><span class="identifier">tree_node</span><span class="special">(</span><span class="identifier">T </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">v</span><span class="special">);<br> </span><span class="identifier">tree_node</span><span class="special">(</span><span class="identifier">T </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">v</span><span class="special">, </span><span class="identifier">children_t </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">c</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">tree_node</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp; </span><span class="identifier">x</span><span class="special">);<br> </span><span class="special">};</span></code></pre> <p> This class is simply used to separate the tree framework from the data stored in the tree. It is a generic node and any type can be stored inside it and acessed - via the data member value. The default type for T is <tt>node_val_data</tt>.</p> + via the data member value. The default type for T is <tt>node_val_data</tt>.<br>该类只是被用于将分析树框架与树中所存数据分离开。 它是一个泛型的节点,任意类型都可以保存在其之内且通过数据成员 value 来访问。 T 的缺省类型是 <tt>node_val_data</tt>.</p>
 <a name="node_val_data"></a>
 <h3>node_val_data</h3>
<p> The <tt>node_val_data</tt> class contains the actual information about each node. This includes the text or token sequence that was parsed, an <tt>id</tt> that indicates which rule created the node, a boolean flag that indicates whether the node was marked as a root node, and an optional user-specified value. This
-  is the interface:</p>
+ is the interface:<br>类 <tt>node_val_data</tt> 包含了关于每个节点的实际信 息。其中包含被分析的文本或记号序列,一个 <tt>id</tt> + 用于表示是哪个规则创建了该节点,一个布尔 flag 表示该节点是否被标记为根节 点,以及一个可选的用户指定的值。接口如下:</p> <pre> <code><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT </span><span class="special">= </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">*, </span><span class="keyword">typename </span><span class="identifier">ValueT </span><span class="special">= </span><span class="identifier">nil_t</span><span class="special">&gt;<br> </span><span class="keyword">struct </span><span class="identifier">node_val_data<br> </span><span class="special">{<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier">IteratorT</span><span class="special">&gt;::</span><span class="identifier">value_type </span><span class="identifier">value_type</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">value_type</span><span class="special">&gt; </span><span class="identifier">container_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">iterator </span><span class="identifier">iterator_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="keyword">typename </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">const_iterator </span><span class="identifier">const_iterator_t</span><span class="special">;<br><br> </span><span class="identifier">node_val_data</span><span class="special">();<br> </span><span class="identifier">node_val_data</span><span class="special">(</span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">_first</span><span class="special">, </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">_last</span><span class="special">);<br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT2</span><span class="special">&gt;<br> </span><span class="identifier">node_val_data</span><span class="special">(</span><span class="identifier">IteratorT2 </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">_first</span><span class="special">, </span><span class="identifier">IteratorT2 </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">_last</span><span class="special">);<br> </span><span class="keyword">void </span><span class="identifier">swap</span><span class="special">(</span><span class="identifier">node_val_data</span><span class="special">&amp; </span><span class="identifier">x</span><span class="special">);<br><br> </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">iterator </span><span class="identifier">begin</span><span class="special">();<br> </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">const_iterator </span><span class="identifier">begin</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">iterator </span><span class="identifier">end</span><span class="special">();<br> </span><span class="identifier">container_t</span><span class="special">::</span><span class="identifier">const_iterator </span><span class="identifier">end</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br><br> </span><span class="keyword">bool </span><span class="identifier">is_root</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">is_root</span><span class="special">(</span><span class="keyword">bool </span><span class="identifier">b</span><span class="special">);<br><br> </span><span class="identifier">parser_id </span><span class="identifier">id</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">id</span><span class="special">(</span><span class="identifier">parser_id </span><span class="identifier">r</span><span class="special">);<br><br> </span><span class="identifier">ValueT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">value</span><span class="special">() </span><span class="keyword">const</span><span class="special">;<br> </span><span class="keyword">void </span><span class="identifier">value</span><span class="special">(</span><span class="identifier">ValueT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">v</span><span class="special">);<br> </span><span class="special">};<br></span></code></pre>
 <a name="parser_id__checking_and_setting"></a>
-<h3>parser_id, checking and setting</h3>
+<h3>parser_id, checking and setting 检查与设置</h3>
<p> If a node is generated by a rule, it will have an <tt>id</tt> set. Each rule has an id that it sets of all nodes generated by that rule. The id is of type <tt><a href="rule.html#tag">parser_id</a></tt>. The default id of each rule
@@ -194,47 +205,53 @@
to the rules, and may not be able to compare addresses. So, you can override the default id used by each rule by <a href="rule.html#tag">giving it a specific ID</a>. Then, when processing the tree you can call <tt>node_val_data::id()</tt>
-  to see which rule created that node.</p>
+ to see which rule created that node.<br>如果一个节点由一个规则生成了,它 将具有一个 <tt>id</tt> 集。每个规则都有一个 id,它将被设入由该规则生成的所有 规则。id 的类型为 + <tt><a href="rule.html#tag">parser_id</a></tt>。每个规则的缺省 id 被设置 为该规则的地址(转换为一个整数)。这并不总是最方便的,因为处理该分析树的代码并 不能访问该规则,也不可能比较该地址。因此,你可以通过 <a href="rule.html#tag">指定特定ID</a> 来重载每个规则所使用的缺省 id。然后,在 处理该分析树时,你就可以调用 <tt>node_val_data::id()</tt>
+  来查看是哪个规则创建了该节点。</p>
 <a name="structure_layout_of_a_parse_tree"></a>
-<h2>structure/layout of a parse tree</h2>
+<h2>structure/layout of a parse tree 分析树的结构/布局</h2>
 <a name="parse_tree_layout"></a>
-<h3>parse tree layout</h3>
+<h3>parse tree layout 分析树的布局</h3>
<p> The tree is organized by the rules. Each rule creates a new level in the tree. All parsers attached to a rule create a node when a sucessful match is made. These nodes become children of a node created by the rule. So, the following
-  code:</p>
+ code:<br>分析树由规则组成。每个规则在树中创建一个新的层级。附加至某个规则 的所有分析器在成功匹配时创建一个节点。这些节点成为由该规则所创建的一个节点的 子节点。因此,以下代码:</p> <pre> <code><span class="identifier">rule_t </span><span class="identifier">myrule </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'a'</span><span class="special">) </span><span class="special">&gt;&gt; </span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="special">*</span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'b'</span><span class="special">);<br> </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">input </span><span class="special">= </span><span class="string">"a,bb"</span><span class="special">;<br> </span><span class="identifier">scanner_t </span><span class="identifier">scanner</span><span class="special">(</span><span class="identifier">input</span><span class="special">, </span><span class="identifier">input </span><span class="special">+ </span><span class="identifier">strlen</span><span class="special">(</span><span class="identifier">input</span><span class="special">));<br> </span><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="identifier">m </span><span class="special">= </span><span class="identifier">myrule</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">scanner</span><span class="special">);<br></span></code></pre> <p> When executed, this code would return a tree_match, m. <tt>m.trees[0]</tt>
-  would contain a tree like this:</p>
-<table border="0" align="center">
+ would contain a tree like this:<br>在执行时,该代码将返回一个 tree_match,m. <tt>m.trees[0]</tt>
+  将包含如下的一棵树:</p>
+<table align="center" border="0">
   <tbody><tr>
-    <td><img src="theme/trees1.png" width="253" height="151"></td>
+    <td><img src="theme/trees1.png" height="151" width="253"></td>
   </tr>
 </tbody></table>
<p> The root node would not contain any text, and it's id would be set to the address of myrule. It would have four children. Each child's id would be set to the address of myrule, would contain the text as shown in the diagram, and
-  would have no children.</p>
+ would have no children.<br>根节点不包含任何文本,其 id 被设为 myrule 的地 址。它有四个子节点。每个子节点的 id 都被设为 myrule 的地址,每个子节点包含如 图所示的文本,且不带子节点。</p>
 <a name="ast_layout"></a>
-<h2>ast layout</h2>
-<p> When calling <a href="#ast_parse">ast_parse</a>, the tree gets generated differently.
+<h2>ast layout &nbsp;ast的布局</h2>
+<p> When calling <a href="trees.html#ast_parse">ast_parse</a>, the tree gets generated differently. It mostly works the same as when generating a parse tree. The difference happens - when a rule only generated one sub-node. Instead of creating a new level, <a href="#ast_parse">ast_parse</a> + when a rule only generated one sub-node. Instead of creating a new level, <a href="trees.html#ast_parse">ast_parse</a> will not create a new level, it will just leave the existing node. So, this
-  code:</p>
+ code:<br>调用 <a href="#ast_parse">ast_parse</a> 时,将以不同的方式生成分 析树。该函数与生成一棵分析树几乎一样。差别在于,一个规则只生成一个子节点。 <a href="#ast_parse">ast_parse</a>
+  不会创建新的层级,它只会保留已有节点。因此,以下代码:</p>
<pre> <code><span class="identifier">rule_t </span><span class="identifier">myrule </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'a'</span><span class="special">);<br> </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">input </span><span class="special">= </span><span class="string">"a"</span><span class="special">;<br> </span><span class="identifier">ast_scanner_t </span><span class="identifier">scanner</span><span class="special">(</span><span class="identifier">input</span><span class="special">, </span><span class="identifier">input</span><span class="special">+</span><span class="identifier">strlen</span><span class="special">(</span><span class="identifier">input</span><span class="special">));<br> </span><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="identifier">m </span><span class="special">= </span><span class="identifier">myrule</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">scanner</span><span class="special">);<br></span></code></pre> <p> will generate a single node that contains 'a'. If <tt>tree_match_policy</tt> had been used instead of <tt>ast_match_policy</tt>, the tree would have looked
-  like this:</p>
-<table border="0" align="center">
+ like this:<br>将生成一个包含 'a' 的单节点为。如果使用了 <tt>tree_match_policy</tt>
+  来替代 <tt>ast_match_policy</tt>,则分析树看起来如下:</p>
+<table align="center" border="0">
   <tbody><tr>
-    <td><img src="theme/trees2.png" width="139" height="151"></td>
+    <td><img src="theme/trees2.png" height="151" width="139"></td>
   </tr>
 </tbody></table>
<p> ast_match_policy has the effect of eliminating intermediate rule levels which are simply pass-through rules. This is not enough to generate abstract syntax - trees, <a href="#root_node_d_and_ast_generation">root_node_d</a> is also needed. <a href="#root_node_d_and_ast_generation">root_node_d</a>
-  will be explained later.</p>
+ trees, <a href="trees.html#root_node_d_and_ast_generation">root_node_d</a> is also needed. <a href="trees.html#root_node_d_and_ast_generation">root_node_d</a> + will be explained later.<br>ast_match_policy 的作用是消除中间那些只是传递 规则的规则层。这不足以生成抽象语法树,<a href="#root_node_d_and_ast_generation">root_node_d</a> 也是需要的。<a href="#root_node_d_and_ast_generation">root_node_d</a>
+  将在稍后解释。</p>
 <a name="switching__gen_pt_node_d____amp__gen_ast_node_d__"></a>
 <h2>switching: gen_pt_node_d[] &amp; gen_ast_node_d[]</h2>
<p> If you want to mix and match the parse tree and ast behaviors in your application,
@@ -246,12 +263,14 @@
 if you use a rule inside of these    directives. &nbsp;The match policy of
 the scanner will have to correspond to the desired behavior. &nbsp;If you
 avoid rules and use primitive parsers or grammars, then you will not have
-problems.</p>
+problems.<br>如果你想在你的应用中混用并匹配分析树和 ast 的行为,你可以使用 <tt>gen_pt_node_d[]</tt> 和 <tt>gen_ast_node_d[]</tt> 指示符。当通过 <tt>gen_pt_node_d</tt> 指示符进行分析时,分析树创建的行为被打开。当使用 <tt>gen_ast_node_d</tt>
+指示符时,内部的分析器将生成一棵使用
+ast 行为的树。注意,如果你在这些指示符内部使用规则,你必须留意你的规则是如 何声明的。扫描器的匹配策略必须与想要的行为相对应。如果你避过规则而使用基本分 析器或语法,则你没有此问题。</p>
 <a name="directives"></a>
-<h2>Directives</h2>
+<h2>Directives 指示符</h2>
<p> There are a few more directives that can be used to control the generation of trees. These directives only effect tree generation. Otherwise, they have
-  no effect.<br>
+ no effect.<br>还有几个指示符可用于控制树的生成。这些指示符仅对树的生成起 作用。其它情况下,它们没有影响。<br>
 </p>
 <a name="no_node_d"></a>
 <h3>no_node_d</h3>
@@ -264,7 +283,7 @@
directive has the same requirements with respect to rules as <tt>gen_pt_node_d</tt> and <tt>gen_ast_node_d</tt> do. See the example file xml_grammar.hpp (in libs/spirit/example/application/xml
   directory) for example
-  usage of <tt>no_node_d[]</tt>.</p>
+ usage of <tt>no_node_d[]</tt>.<br>这个指示符类似于 <tt>gen_pt_node_d</tt> 和 <tt>gen_ast_node_d</tt>,修改内部分析器所用的扫描 器匹配策略。顾名思义,它不进行树生成,完全关闭。如果你的语法中有一部分不需要 出现在树中,这就很有用了。例如:关键字、操作符(<tt>*</tt>, <tt>-</tt>, <tt>&amp;&amp;</tt>, 等等)。通过从树中消除掉这些,可以同时降低内存耗用和分析 时间。这个指示符对规则的要求与 <tt>gen_pt_node_d</tt> 和 <tt>gen_ast_node_d</tt> 一样。有关 <tt>no_node_d[]</tt> 的用例,请见例程 xml_grammar.hpp (位于目录 libs/spirit/example/application/xml)。</p>
 <a name="discard_node_d"></a>
 <h3>discard_node_d</h3>
<p> This directive has a similar purpose to <tt>no_node_d</tt>, but works differently.
@@ -272,113 +291,120 @@
nodes. The generated nodes are discarded and do not appear in the tree. Using <tt>discard_node_d</tt> is slower than <tt>no_node_d</tt>, but it does not suffer from the drawback of having to specify a different rule type for any rule inside
-  it.</p>
+ it.<br>这个指示符的目的与 <tt>no_node_d</tt> 类似,但工作方式不同。它不改 变扫描器的匹配策略,因此内层的分析器仍旧生成节点。生成的节点被忽略,不会出现 在树中。使用 + <tt>discard_node_d</tt> 要慢于 <tt>no_node_d</tt>,但它不会遇到必须为内部 规则指定不同规则类型的问题。</p>
 <a name="leaf_node_d_token_node_d"></a>
 <h3>leaf_node_d/token_node_d</h3>
 <p> Both <tt>leaf_node_t</tt> and <tt>token_node_d</tt> work the same. They
     create a single node for the match generated by the enclosed parser.
     Unlike with earlier versions of Spirit, this directive is an implicit
     lexeme and alters the scanner (see
-    <a href="faq.html#scanner_business">Scanner Business</a>). </p>
+ <a href="faq.html#scanner_business">Scanner Business</a>).<br><tt>leaf_node_t</tt> 和 <tt>token_node_d</tt> 作用相同。它 们为内层分析器所生成的匹配创建单个节点。与Spirit早期的版本不同,这个指示符是 一个隐式词位,并修改了扫描器(见
+    <a href="faq.html#scanner_business">扫描器业务</a>)。 </p>
 <h3>reduced_node_d</h3>
<p> This directive groups together all the nodes generated by the enclosed parser. For earlier versions of Spirit <tt>leaf_node_d</tt> and <tt>token_node_d</tt> were implemented this way. The new implementation of those directives is a lot faster, so <tt>reduced_node_d</tt> is primarily provided for portability
     and can be useful when using a custom node factory (see advanced tree
-    generation, below).</p>
+ generation, below).<br>这个指示符将内层分析器所生成的所有节点组到一起。 对于早期版本的Spirit,<tt>leaf_node_d</tt> 和 <tt>token_node_d</tt> + 也是以此方式实现。这些指示符的新实现要快不少,因此 <tt>reduced_node_d</tt> 主要是为可移植性而提供,使用定制节点工厂时(见下文的 高级树生成)可以使用。</p>
 <h3>infix_node_d</h3>
<p> This is useful for removing separators from lists. It discards all the nodes
-  in even positions. Thus this rule:</p>
+ in even positions. Thus this rule:<br>用于从列表中去掉分隔符。它略过偶数 位置上的所有节点。因此,以下规则:</p> <pre> <code><span class="identifier">rule_t </span><span class="identifier">intlist </span><span class="special">= </span><span class="identifier">infix_node_d</span><span class="special">[ </span><span class="identifier">integer </span><span class="special">&gt;&gt; </span><span class="special">*(</span><span class="literal">',' </span><span class="special">&gt;&gt; </span><span class="identifier">integer</span><span class="special">) </span><span class="special">];</span></code></pre>
-<p> would discard all the comma nodes and keep all the integer nodes.</p>
+<p> would discard all the comma nodes and keep all the integer nodes.<br>将 略过所有逗号节点而保存所有整数节点。</p>
 <a name="discard_first_node_d"></a>
 <h3>discard_first_node_d</h3>
-<p> This discards the first node generated.</p>
+<p> This discards the first node generated.<br>略过生成的第一个节点。</p>
 <a name="discard_last_node_d"></a>
 <h3>discard_last_node_d</h3>
-<p> This discards the last node generated.</p>
+<p> This discards the last node generated.<br>略过生成的最后一个节点。</p>
 <a name="inner_node_d"></a>
 <h3>inner_node_d</h3>
-<p> This discards the first and last node generated.</p>
+<p> This discards the first and last node generated.<br>略过生成的第一个和 最后一个节点。</p>
 <a name="root_node_d_and_ast_generation"></a>
-<h2>root_node_d and ast generation</h2>
+<h2>root_node_d and ast generation &nbsp;root_node_d和ast的生成</h2>
<p> The <tt>root_node_d</tt> directive is used to help out ast generation. It has no effect when generating a parse tree. When a parser is enclosed in <tt>root_node_d</tt>, the node it generates is marked as a root. This affects the way it is treated - when it's added to the list of nodes being generated. Here's an example:</p> + when it's added to the list of nodes being generated. Here's an example:<br>指示符 <tt>root_node_d</tt> 用于协助 ast 的生成。在生成一个分析 树时没有影响。当一个分析器用 <tt>root_node_d</tt> 括起时,它生成的节点被标记 为根。当它被添加到所生成的节点列表中时,这会影响它被对待的方式。以下是一个例 子:</p> <pre> <code><span class="identifier">rule_t </span><span class="identifier">add </span><span class="special">= </span><span class="identifier">integer </span><span class="special">&gt;&gt; </span><span class="special">*(</span><span class="identifier">root_node_d</span><span class="special">[ </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'+'</span><span class="special">) </span><span class="special">] </span><span class="special">&gt;&gt; </span><span class="identifier">integer</span><span class="special">);</span></code></pre>
-<p> When parsing 5+6 the following tree will be generated:</p>
-<table border="0" align="center">
+<p> When parsing 5+6 the following tree will be generated:<br>在分析 5+6 时,将生成以下树:</p>
+<table align="center" border="0">
   <tbody><tr>
     <td><img src="theme/trees3.png"></td>
   </tr>
 </tbody></table>
-<p> When parsing 1+2+3 the following will be generated:</p>
-<table border="0" align="center">
+<p> When parsing 1+2+3 the following will be generated:<br>当分析 1+2+3 时,将生成以下树:</p>
+<table align="center" border="0">
   <tbody><tr>
     <td><img src="theme/trees4.png"></td>
   </tr>
 </tbody></table>
<p> When a new node is created the following rules are used to determine how the
-  tree will be generated:</p>
-<pre><code> Let a be the previously generated node. <br> Let b be the new node.<br><br> If b is a root node then<br><br> b's children become a + b's previous children. <br> a is the new first child of b.<br><br> else if a is a root node and b is not, then<br><br> b becomes the last child of a.<br><br> else<br><br> a and b become siblings.</code></pre> + tree will be generated:<br>当创建一个新节点时,以下规则将被用于确定如何生 成该树:</p> +<pre><code> Let a be the previously generated node. 令a为之前生成的节 点。<br> Let b be the new node. 令b为新节点。<br><br> If b is a root node then 如果b是根节点,则<br><br> b's children become a + b's previous children. b的子节点变为a+b的前一个子节点。<br> a is the new first child of b. a为b的新的首子节点。<br><br> else if a is a root node and b is not, then 否则,如果a是根节点而b不是,则<br><br> b becomes the last child of a. b成为a的尾子节点。<br><br> else 否则 <br><br> a and b become siblings. a和b变为兄弟</code></pre> <p> After parsing leaves the current rule, the root node flag on the top node is turned off. This means that the root_node_d directive only affects the current
-  rule.</p>
-<p> <img height="16" width="15" src="theme/lens.gif"> The example <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a> demonstrates the use of root_node_d and <a href="#ast_parse">ast_parse</a>. The full source code can be <a href="../example/fundamental/ast_calc.cpp">viewed here</a>. This is part of the Spirit distribution.</p> + rule.<br>在分析了当前规则的其余部分后,顶部节点的根节点标志被关闭。这意味 着 root_node_d 指示符仅作用于当前规则。</p> +<p> <img src="theme/lens.gif" height="16" width="15"> The example <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a> demonstrates the use of root_node_d and <a href="#ast_parse">ast_parse</a>. The full source code can be <a href="../example/fundamental/ast_calc.cpp">viewed here</a>. This is part of the Spirit distribution.<br><img src="theme/lens.gif" height="16" width="15"> 例子 <a href="../example/fundamental/ast_calc.cpp">ast_calc.cpp</a> 示范了 root_node_d 和 <a href="trees.html#ast_parse">ast_parse</a> 的使用。完整的源 代码可 <a href="../example/fundamental/ast_calc.cpp">在此查看</a>。这是 Spirit发布包的一部分。</p>
 <a name="parse_tree_iterator"></a>
 <h2>parse_tree_iterator</h2>
<p> The <tt>parse_tree_iterator</tt> class allows you to parse a tree using spirit. The class iterates over the tokens in the leaf nodes in the same order they were created. The <tt>parse_tree_iterator</tt> is templated on <tt>ParseTreeMatchT</tt>. It is constructed with a container of trees, and a position to start. Here is
-  an example usage:</p>
-<pre> <code><span class="identifier">rule_t </span><span class="identifier">myrule </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'a'</span><span class="special">);<br> </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">input </span><span class="special">= </span><span class="string">"a"</span><span class="special">;<br><br> </span><span class="comment">// generate parse tree<br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt; </span><span class="identifier">i </span><span class="special">= </span><span class="identifier">pt_parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">, </span><span class="identifier">myrule</span><span class="special">);<br><br> </span><span class="keyword">typedef </span><span class="identifier">parse_tree_iterator</span><span class="special">&lt;</span><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="special">&gt; </span><span class="identifier">parse_tree_iterator_t</span><span class="special">;<br><br> </span><span class="comment">// create a first and last iterator to work off the tree<br> </span><span class="identifier">parse_tree_iterator_t </span><span class="identifier">first</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">trees</span><span class="special">, </span><span class="identifier">i</span><span class="special">.</span><span class="identifier">trees</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> </span><span class="identifier">parse_tree_iterator_t </span><span class="identifier">last</span><span class="special">;<br><br> </span><span class="comment">// parse the tree<br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">parse_tree_iterator_t</span><span class="special">&gt; </span><span class="identifier">tree_parser </span><span class="special">=...<br> </span><span class="identifier">tree_parser</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">);<br></span></code></pre> + an example usage:<br>类 <tt>parse_tree_iterator</tt> 允许你用spirit分析一 棵树。该类以创建时的相同顺序迭代叶子节点中的记号。 <tt>parse_tree_iterator</tt> 按 <tt>ParseTreeMatchT</tt> 模板化。它以一个树 容器和一个开始位置进行构造。以下是一个用例:</p> +<pre> <code><span class="identifier">rule_t </span><span class="identifier">myrule </span><span class="special">= </span><span class="identifier">ch_p</span><span class="special">(</span><span class="literal">'a'</span><span class="special">);<br> </span><span class="keyword">char </span><span class="keyword">const</span><span class="special">* </span><span class="identifier">input </span><span class="special">= </span><span class="string">"a"</span><span class="special">;<br><br> </span><span class="comment">// generate parse tree 生成分析树<br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;&gt; </span><span class="identifier">i </span><span class="special">= </span><span class="identifier">pt_parse</span><span class="special">(</span><span class="identifier">input</span><span class="special">, </span><span class="identifier">myrule</span><span class="special">);<br><br> </span><span class="keyword">typedef </span><span class="identifier">parse_tree_iterator</span><span class="special">&lt;</span><span class="identifier">tree_match</span><span class="special">&lt;&gt; </span><span class="special">&gt; </span><span class="identifier">parse_tree_iterator_t</span><span class="special">;<br><br> </span><span class="comment">// create a first and last iterator to work off the tree 创建首尾迭代器,以处理该树<br> </span><span class="identifier">parse_tree_iterator_t </span><span class="identifier">first</span><span class="special">(</span><span class="identifier">i</span><span class="special">.</span><span class="identifier">trees</span><span class="special">, </span><span class="identifier">i</span><span class="special">.</span><span class="identifier">trees</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());<br> </span><span class="identifier">parse_tree_iterator_t </span><span class="identifier">last</span><span class="special">;<br><br> </span><span class="comment">// parse the tree 分析该树<br> </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">parse_tree_iterator_t</span><span class="special">&gt; </span><span class="identifier">tree_parser </span><span class="special">=...<br> </span><span class="identifier">tree_parser</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">);<br></span></code></pre>
 <p> <a name="advanced_tree_generation"></a>
 </p>
-<h2>advanced tree generation</h2>
+<h2>advanced tree generation 高级树生成</h2>
 <a name="node_value"></a>
-<h3>node value</h3>
+<h3>node value 节点值</h3>
<p> The <tt>node_val_data</tt> can contain a value. By default it contains a <tt>void_t</tt>, which is an empty class. You can specify the type, using a template parameter, which will then be stored in every node. The type must be default constructible,
-  and assignable. You can get and set the value using</p>
+ and assignable. You can get and set the value using<br><tt>node_val_data</tt> 可以包含一个值。缺省情况下,它包含一个空类 <tt>void_t</tt>。你可以用模板参数指定新的类型,该类型将被保存在每个节点中。 该类型必须是可缺省构造和可赋值的。要获取或设置该值,你可以用</p> <pre> <code><span class="identifier">ValueT </span><span class="identifier">node_val_data</span><span class="special">::</span><span class="identifier">value</span><span class="special">;</span></code></pre>
-<p> and</p>
+<p> and<br>和</p>
<pre> <code><span class="keyword">void </span><span class="identifier">node_val_data</span><span class="special">::</span><span class="identifier">value</span><span class="special">(</span><span class="identifier">Value </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">value</span><span class="special">);</span></code></pre> -<p> To specify the value type, you must use a different <a href="#node_val_data">node_val_data - </a>factory than the default. The following example shows how to modify the factory to store and retrieve a double inside each <span class="identifier">node_val_data</span>. -<pre> <span class=keyword>typedef </span><span class=identifier>node_val_data_factory</span><span class=special>&lt;</span><span class=keyword>double</span><span class=special>&gt; </span><span class=identifier>factory_t</span><span class=special>;<br> </span><span class=identifier>my_grammar </span><span class=identifier>gram</span><span class=special>;<br> </span><span class=identifier>my_skip_grammar </span><span class=identifier>skip</span><span class=special>;<br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>iterator_t</span><span class=special>, </span><span class=identifier>factory_t</span><span class=special>&gt; </span><span class=identifier>i </span><span class=special>= <br> </span><span class=identifier>ast_parse</span><span class=special>&lt;</span><span class=identifier>factory_t</span><span class=special>&gt;(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>gram</span><span class=special>, </span><span class=identifier>skip</span><span class=special>);<br> // access the double in the root node<br> </span><span class=keyword>double </span><span class=identifier>d </span><span class=special>= </span><span class=identifier>i</span><span class=special>.</span><span class=identifier>trees</span><span class=special>.</span><span class=identifier>begin</span><span class=special>()-&gt;</span><span class=identifier>value</span><span class=special>;<br></span></pre>
-</p>
+<p> To specify the value type, you must use a different <a href="trees.html#node_val_data">node_val_data + </a>factory than the default. The following example shows how to modify the factory to store and retrieve a double inside each <span class="identifier">node_val_data</span>.<br>要指定这个值类型,你必须使用一个 不同与缺省值的 <a href="#node_val_data">node_val_data + </a>工厂。以下例子示范了如何修改该工厂以保存并取出每个 <span class="identifier">node_val_data</span> 中的 double 值。 +</p><pre> <span class="keyword">typedef </span><span class="identifier">node_val_data_factory</span><span class="special">&lt;</span><span class="keyword">double</span><span class="special">&gt; </span><span class="identifier">factory_t</span><span class="special">;<br> </span><span class="identifier">my_grammar </span><span class="identifier">gram</span><span class="special">;<br> </span><span class="identifier">my_skip_grammar </span><span class="identifier">skip</span><span class="special">;<br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">i </span><span class="special">= <br> </span><span class="identifier">ast_parse</span><span class="special">&lt;</span><span class="identifier">factory_t</span><span class="special">&gt;(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">, </span><span class="identifier">gram</span><span class="special">, </span><span class="identifier">skip</span><span class="special">);<br> // access the double in the root node 访问根节点中的double<br> </span><span class="keyword">double </span><span class="identifier">d </span><span class="special">= </span><span class="identifier">i</span><span class="special">.</span><span class="identifier">trees</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()-&gt;</span><span class="identifier">value</span><span class="special">;<br></span></pre>
+<p></p>
 <a name="access_node_d"></a>
 <h3>access_node_d</h3>
 <p> Now, you may be wondering, "What good does it do to have a value I can
   store in each node, but not to have any way of setting it?" Well, that's
what <tt>access_node_d</tt> is for. <tt>access_node_d</tt> is a directive. It
-  allows you to attach an action to it, like this:</p>
+ allows you to attach an action to it, like this:<br>现在,你可能会奇 怪,“如果我只能保存一个值到每个节点中,而没有方法设置它,有什么好处?”。好 的,所以需要 <tt>access_node_d</tt>。<tt>access_node_d</tt> 是一个指示符。它 允许你附加一个动作,如:</p> <pre> <code><span class="identifier">access_node_d</span><span class="special">[...</span><span class="identifier">some </span><span class="identifier">parsers</span><span class="special">...][</span><span class="identifier">my_action</span><span class="special">()]</span></code></pre> <p> The attached action will be passed 3 parameters: A reference to the root node of the tree generated by the parser, and the current first and last iterators.
-  The action can set the value stored in the node.</p>
+ The action can set the value stored in the node.<br>附加的动作有3个参 数:由该分析器生成的树的根节点的一个引用、当前的 first 和 last 迭代器。该动 作可以设置保存在节点中的值。</p>
 <a name="tree_node_factories"></a>
-<h3>Tree node factories</h3>
+<h3>Tree node factories 树节点工厂</h3>
<p> By setting the factory, you can control what type of nodes are created and how they are created. There are 3 predefined factories: <tt>node_val_data_factory</tt>, <tt>node_all_val_data_factory</tt>, and <tt>node_iter_data_factory</tt>. You
-  can also create your own factory to support your own node types.</p>
-<p> Using factories with grammars is quite easy, you just need to specify the factory type as explicit template parameter to the free ast_parse function:</p> -<pre> <span class=keyword>typedef </span><span class=identifier>node_iter_data_factory</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt; </span><span class=identifier>factory_t</span><span class=special>;<br> </span><span class=identifier>my_grammar </span><span class=identifier>gram</span><span class=special>;<br> </span><span class=identifier>my_skip_grammar </span><span class=identifier>skip</span><span class=special>;<br> </span><span class=identifier>tree_parse_info</span><span class=special>&lt;</span><span class=identifier>iterator_t</span><span class=special>, </span><span class=identifier>factory_t</span><span class=special>&gt; </span><span class=identifier>i </span><span class=special>= <br> </span><span class=identifier>ast_parse</span><span class=special>&lt;</span><span class=identifier>factory_t</span><span class=special>&gt;(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>, </span><span class=identifier>gram</span><span class=special>, </span><span class=identifier>skip</span><span class=special>);<br></span></pre> + can also create your own factory to support your own node types.<br>通过 设置工厂,你可以控制创建何种类型的节点以及如何创建它们。有3个预定义的工 厂:<tt>node_val_data_factory</tt>, + <tt>node_all_val_data_factory</tt>, 和 <tt>node_iter_data_factory</tt>。 你也可以创建你自己的工厂以支持你自己的节点类型。</p><p> Using factories with grammars is quite easy, you just need to
+specify the factory type as explicit template parameter to the free
+ast_parse function:<br>和语法一起使用工厂非常容易,你只需要指定工厂类型为自 由函数 ast_parse 显式的模板参数:</p> +<pre> <span class="keyword">typedef </span><span class="identifier">node_iter_data_factory</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt; </span><span class="identifier">factory_t</span><span class="special">;<br> </span><span class="identifier">my_grammar </span><span class="identifier">gram</span><span class="special">;<br> </span><span class="identifier">my_skip_grammar </span><span class="identifier">skip</span><span class="special">;<br> </span><span class="identifier">tree_parse_info</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">i </span><span class="special">= <br> </span><span class="identifier">ast_parse</span><span class="special">&lt;</span><span class="identifier">factory_t</span><span class="special">&gt;(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special">, </span><span class="identifier">gram</span><span class="special">, </span><span class="identifier">skip</span><span class="special">);<br></span></pre> <p> Instead, using the factory directly with rules is slightly harder because the factory is a template parameter to the scanner match policy, so you must use a
-  custom scanner:</p>
+ custom scanner:<br>相反,直接与规则一起使用工厂会稍难一些,因为工厂是扫描 器匹配策略的一个模板参数,因此你必须使用定制扫描器:</p> <pre> <code><span class="keyword">typedef </span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">void_t </span><span class="identifier">value_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">node_val_data_factory</span><span class="special">&lt;</span><span class="identifier">value_t</span><span class="special">&gt; </span><span class="identifier">factory_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">ast_match_policy</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_policy_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">scanner</span><span class="special">&lt;</span><span class="identifier">iterator_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> scanner_policies</span></code><code><span class="identifier"></span><span class="special">&lt;</span></code><code><span class="identifier">iter_policy_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> match_policy_t</span><span class="special">&gt;</span></code><code><span class="identifier"></span><span class="special"> &gt;</span></code><code><span class="special"> </span><span class="identifier">scanner_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">scanner_t</span><span class="special"></span><span class="identifier"></span><span class="special">&gt; </span><span class="identifier">rule_t</span><span class="special">;<br><br> </span><span class="identifier">rule_t </span><span class="identifier">r </span><span class="special">=...;<br><br></span></code><code><span class="special"> </span><span class="identifier">scanner_t </span><span class="identifier">scan </span><span class="special">= </span><span class="identifier">scanner_t</span><span class="special"></span><span class="identifier"></span><span class="special">(</span><span class="identifier">first</span><span class="special">, </span><span class="identifier">last</span><span class="special"></span><span class="identifier"></span><span class="special">);<br></span></code><code><span class="special"></span></code><code><span class="special"> </span><span class="identifier">match_t </span><span class="identifier">hit </span><span class="special">= </span><span class="identifier">r</span><span class="special">.</span><span class="identifier">parse</span><span class="special">(</span><span class="identifier"></span><span class="special"></span><span class="identifier"></span><span class="special"></span><span class="identifier">scan</span><span class="special">);</span></code></pre>
 <a name="node_val_data_factory"></a>
 <h3>node_val_data_factory</h3>
<p> This is the default factory. It creates <tt>node_val_data</tt> nodes. Leaf nodes contain a copy of the matched text, and intermediate nodes don't. <tt>node_val_data_factory</tt> has one template parameter: <tt>ValueT</tt>. <tt>ValueT</tt> specifies the type
-  of value that will be stored in the <tt>node_val_data</tt>.</p>
+ of value that will be stored in the <tt>node_val_data</tt>.<br>这是缺省的 工厂。它创建 <tt>node_val_data</tt> 节点。叶节点包含被匹配文本的拷贝,而中间 节点则不包含。<tt>node_val_data_factory</tt> + 有一个模板参数:<tt>ValueT</tt>. <tt>ValueT</tt> 指定保存在 <tt>node_val_data</tt> 中的值的类型。</p>
 <a name="node_val_data_factory"></a>
 <h3>node_all_val_data_factory</h3>
<p> This factory also creates <tt>node_val_data</tt>. The difference between it
@@ -386,7 +412,7 @@
text that spans it. This means that the root node will contain a copy of the entire parsed input sequence. <tt>node_all_val_data_factory</tt> has one template parameter: <tt>ValueT</tt>. <tt>ValueT</tt> specifies the type of value that
-  will be stored in the <tt>node_val_data</tt>.</p>
+ will be stored in the <tt>node_val_data</tt>.<br>这个工厂也创建 <tt>node_val_data</tt>。与 <tt>node_val_data_factory</tt> 不同的是,<b>每个 </b>节点都包含与之相关的所有文本。这意味着根节点将包含整个被分析的输入序列的 拷贝。<tt>node_all_val_data_factory</tt> 有一个模板参数:<tt>ValueT</tt>. <tt>ValueT</tt> 指定保存在 <tt>node_val_data</tt> 中的值的类型。</p>
 <a name="node_iter_data_factory"></a>
 <h3>node_iter_data_factory</h3>
<p> This factory creates the <tt>parse_tree_iter_node</tt>. This node stores iterators
@@ -395,11 +421,12 @@
not a good idea to use the <tt>multi_pass</tt> iterator with this type of node. All levels of the tree will contain a begin and end iterator. <tt>node_iter_data_factory</tt> has one template parameter: <tt>ValueT</tt>. <tt>ValueT</tt> specifies the type
-  of value that will be stored in the node_val_data.</p>
+ of value that will be stored in the node_val_data.<br>这个工厂创建 <tt>parse_tree_iter_node</tt>。这个节点保存输入序列的迭代器而不是拷贝。它可 以占用更少的内存。但是,输入序列必须在树的整个生命周期中保存可用,而且将 <tt>multi_pass</tt> 迭代器与这种节点类型一起使用也不是好的主意。树的所有层级 都将包含一个 begin 和 end 迭代器。 <tt>node_iter_data_factory</tt> + 有一个模板参数:<tt>ValueT</tt>. <tt>ValueT</tt> 指定保存在 <tt>node_val_data</tt> 中的值的类型。</p>
 <a name="custom"></a>
-<h3>custom</h3>
-<p> You can create your own factory. It should look like this:</p>
-<pre> <code><span class="keyword">class </span><span class="identifier">my_factory<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// This inner class is so that the factory can simulate<br> // a template template parameter<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">factory<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// This is your node type<br> </span><span class="keyword">typedef </span><span class="identifier">my_node_type </span><span class="identifier">node_t</span><span class="special">;<br><br> </span><span class="keyword">static </span><span class="identifier">node_t </span><span class="identifier">create_node</span><span class="special">(<br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first</span><span class="special">, </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last</span><span class="special">, </span><span class="keyword">bool </span><span class="identifier">is_leaf_node</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// create a node and return it.<br> </span><span class="special">}<br><br> </span><span class="comment">// This function is used by the reduced_node directive.<br> // If you don't use it, then you can leave this function<br> // unimplemented.<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ContainerT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="identifier">node_t </span><span class="identifier">group_nodes</span><span class="special">(</span><span class="identifier">ContainerT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">nodes</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// Group all the nodes into one and return it.<br> </span><span class="special">}<br> </span><span class="special">};<br> </span><span class="special">};<br><br><br> </span><span class="comment">// Typedefs to use my_factory<br> </span><span class="keyword">typedef </span><span class="identifier">my_factory </span><span class="identifier">factory_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match_policy</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_policy_t</span><span class="special">;<br></span></code><code><span class="special"><br> </span><span class="comment">// Typedefs if you are using rules instead of grammars<br></span></code><code><span class="special"> </span><span class="keyword">typedef </span><span class="identifier">scanner</span><span class="special">&lt;</span><span class="identifier">iterator_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> scanner_policies</span></code><code><span class="identifier"></span><span class="special">&lt;</span></code><code><span class="identifier">iter_policy_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> match_policy_t</span><span class="special">&gt;</span></code><code><span class="identifier"></span><span class="special"> &gt;</span></code><code><span class="special"> </span><span class="identifier">scanner_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">scanner_t</span><span class="special"></span><span class="identifier"></span><span class="special">&gt; </span><span class="identifier">rule_t</span><span class="special">;<br></span></code><code><span class="special"></span><span class="special"><br></span></code></pre><table border="0"><tbody><tr><td width="10"><br>
+<h3>custom 定制</h3>
+<p> You can create your own factory. It should look like this:<br>你可以创 建自己的工厂。它应该看起来如下:</p> +<pre> <code><span class="keyword">class </span><span class="identifier">my_factory<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// This inner class is so that the factory can simulate 内层类令工厂可以模仿<br> // a template template parameter 一个模板模板参数 <br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">IteratorT</span><span class="special">&gt;<br> </span><span class="keyword">class </span><span class="identifier">factory<br> </span><span class="special">{<br> </span><span class="keyword">public</span><span class="special">:<br><br> </span><span class="comment">// This is your node type 这是你的节点类型 <br> </span><span class="keyword">typedef </span><span class="identifier">my_node_type </span><span class="identifier">node_t</span><span class="special">;<br><br> </span><span class="keyword">static </span><span class="identifier">node_t </span><span class="identifier">create_node</span><span class="special">(<br> </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">first</span><span class="special">, </span><span class="identifier">IteratorT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">last</span><span class="special">, </span><span class="keyword">bool </span><span class="identifier">is_leaf_node</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// create a node and return it. 创建一个节点并返回它。<br> </span><span class="special">}<br><br> </span><span class="comment">// This function is used by the reduced_node directive.<br> // If you don't use it, then you can leave this function<br> // unimplemented. 这个函数由reduced_node指示符使用。如果你不用 它,<br> // 那么你可以不实现该函数。<br><br> </span><span class="keyword">template </span><span class="special">&lt;</span><span class="keyword">typename </span><span class="identifier">ContainerT</span><span class="special">&gt;<br> </span><span class="keyword">static </span><span class="identifier">node_t </span><span class="identifier">group_nodes</span><span class="special">(</span><span class="identifier">ContainerT </span><span class="keyword">const</span><span class="special">&amp; </span><span class="identifier">nodes</span><span class="special">)<br> </span><span class="special">{<br> </span><span class="comment">// Group all the nodes into one and return it. 将所有节点组 成一群并返回它。<br> </span><span class="special">}<br> </span><span class="special">};<br> </span><span class="special">};<br><br><br> </span><span class="comment">// Typedefs to use my_factory<br> </span><span class="keyword">typedef </span><span class="identifier">my_factory </span><span class="identifier">factory_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">tree_match_policy</span><span class="special">&lt;</span><span class="identifier">iterator_t</span><span class="special">, </span><span class="identifier">factory_t</span><span class="special">&gt; </span><span class="identifier">match_policy_t</span><span class="special">;<br></span></code><code><span class="special"><br> </span><span class="comment">// Typedefs if you are using rules instead of grammars 如果你用规则替代语法<br></span></code><code><span class="special"> </span><span class="keyword">typedef </span><span class="identifier">scanner</span><span class="special">&lt;</span><span class="identifier">iterator_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> scanner_policies</span></code><code><span class="identifier"></span><span class="special">&lt;</span></code><code><span class="identifier">iter_policy_t</span></code><code><span class="special">,</span></code><code><span class="identifier"> match_policy_t</span><span class="special">&gt;</span></code><code><span class="identifier"></span><span class="special"> &gt;</span></code><code><span class="special"> </span><span class="identifier">scanner_t</span><span class="special">;<br> </span><span class="keyword">typedef </span><span class="identifier">rule</span><span class="special">&lt;</span><span class="identifier">scanner_t</span><span class="special"></span><span class="identifier"></span><span class="special">&gt; </span><span class="identifier">rule_t</span><span class="special">;<br></span></code><code><span class="special"></span><span class="special"><br></span></code></pre><table border="0"><tbody><tr><td width="10"><br>
 </td>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> <td width="30"><a href="symbols.html"><img src="theme/l_arr.gif" border="0"></a></td>
@@ -407,7 +434,7 @@
   </tr>
 </tbody></table>
 <hr size="1">
-<p class="copyright">Copyright &copy; 2001-2002 Daniel C. Nuffer<br>Revised 2007 Copyright &copy; Tobias Schwinger<br> +<p class="copyright">Copyright © 2001-2002 Daniel C. Nuffer<br>Revised 2007 Copyright © Tobias Schwinger<br>
   <br>
<font size="2">Use, modification and distribution is subject to the Boost Software
     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
=======================================
--- /trunk/libs/spirit/classic/index.html       Sun Sep 20 23:13:57 2009
+++ /trunk/libs/spirit/classic/index.html       Mon Oct 12 20:27:43 2009
@@ -852,7 +852,7 @@



-    <td class="toc_cells_L1"><a href="doc/multi_pass.html">多通路 </a></td>
+ <td class="toc_cells_L1"><a href="doc/multi_pass.html">多次遍历 </a></td>



@@ -1033,7 +1033,7 @@



- <td class="toc_cells_L0"><a href="doc/acknowledgments.html">致谢 </a></td> + <td class="toc_cells_L0"><a href="doc/acknowledgments.html">鸣谢 </a></td>



Other related posts:

  • » [boost-doc-zh] r336 committed - Spirit库译文,由 alai04 翻译,第三批 - codesite-noreply