semantic_actions.html 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <html>
  2. <head>
  3. <title>Semantic Actions</title>
  4. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  5. <link rel="stylesheet" href="theme/style.css" type="text/css">
  6. </head>
  7. <body>
  8. <table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2">
  9. <tr>
  10. <td width="10">
  11. </td>
  12. <td width="85%">
  13. <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Semantic Actions</b></font>
  14. </td>
  15. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td>
  16. </tr>
  17. </table>
  18. <br>
  19. <table border="0">
  20. <tr>
  21. <td width="10"></td>
  22. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  23. <td width="30"><a href="subrules.html"><img src="theme/l_arr.gif" border="0"></a></td>
  24. <td width="30"><a href="indepth_the_parser.html"><img src="theme/r_arr.gif" border="0"></a></td>
  25. </tr>
  26. </table>
  27. <p>Semantic actions have the form: <b>expression[action]</b></p>
  28. <p>Ultimately, after having defined our grammar and having generated a corresponding
  29. parser, we will need to produce some output and do some work besides syntax
  30. analysis; unless, of course, what we want is merely to check for the conformance
  31. of an input with our grammar, which is very seldom the case. Semantic actions
  32. may be attached to any expression at any level within the parser hierarchy.
  33. An action is a C/C++ function or function object that will be called if a match
  34. is found in the particular context where it is attached. The action function
  35. serves as a hook into the parser and may be used to, for example:</p>
  36. <blockquote>
  37. <p><img src="theme/bullet.gif" width="13" height="13"> Generate output from
  38. the parser (ASTs, for example)<br>
  39. <img src="theme/bullet.gif" width="13" height="13"> Report warnings or errors<br>
  40. <img src="theme/bullet.gif" width="13" height="13"> Manage symbol tables</p>
  41. </blockquote>
  42. <h2>Generic Semantic Actions (Transduction Interface)</h2>
  43. <p>A generic semantic action can be any free function or function object that
  44. is compatible with the interface:</p>
  45. <pre><code><font color="#000000"><span class=identifier></span><span class=keyword> void </span><span class=identifier>f</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></font></code></pre>
  46. <p>where <tt>IteratorT</tt> is the type of iterator used, <tt>first</tt> points
  47. to the current input and <tt>last</tt> points to one after the end of the input
  48. (identical to STL iterator ranges). A function object (functor) should have
  49. a member <tt>operator()</tt> with the same signature as above:</p>
  50. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>my_functor
  51. </span><span class=special>{
  52. </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>;
  53. </span><span class=special>};</span></font></code></pre>
  54. <p>Iterators pointing to the matching portion of the input are passed into the
  55. function/functor.</p>
  56. <p>In general, semantic actions accept the first-last iterator pair. This is the
  57. transduction interface. The action functions or functors receive the unprocessed
  58. data representing the matching production directly from the input. In many cases,
  59. this is sufficient. Examples are source to source translation, pre-processing,
  60. etc. </p>
  61. <h3>Example:</h3>
  62. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>void
  63. </span><span class=identifier>my_action</span><span class=special>(</span><span class=keyword>char const</span><span class=special>* </span><span class=identifier>first</span><span class=special>, </span><span class=keyword>char const</span><span class=special>* </span><span class=identifier>last</span><span class=special>)
  64. {
  65. </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special> </span><span class="identifier">str</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>);
  66. </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=identifier>str </span><span class=special>&lt;&lt; </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>endl</span><span class=special>;
  67. }
  68. </span><span class=identifier>rule</span><span class=special>&lt;&gt; </span><span class=identifier>myrule </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>&gt;&gt; </span><span class=identifier>d</span><span class=special>))[&</span><span class=identifier>my_action</span><span class=special>];</span></font></code></pre>
  69. <p>The function <tt>my_action</tt> will be called whenever the expression <tt>(a
  70. | b | *(c &gt;&gt; d)</tt> matches a portion of the input stream while parsing.
  71. Two iterators, <tt>first</tt> and <tt>last</tt>, are passed into the function.
  72. These iterators point to the start and end, respectively, of the portion of
  73. input stream where the match is found.</p>
  74. <h3>Const-ness:</h3>
  75. <p>With functors, take note that the <tt>operator()</tt> should be <tt>const</tt>.
  76. This implies that functors are immutable. One may wish to have some member variables
  77. that are modified when the action gets called. This is not a good idea. First
  78. of all, functors are preferably lightweight. Functors are passed around a lot
  79. and it would incur a lot of overhead if the functors are heavily laden. Second,
  80. functors are passed by value. Thus, the actual functor object that finally attaches
  81. to the parser, will surely not be the original instance supplied by the client.
  82. What this means is that changes to a functor's state will not affect the original
  83. functor that the client passed in since they are distinct copies. If a functor
  84. needs to update some state variables, which is often the case, it is better
  85. to use references to external data. The following example shows how this can
  86. be done:</p>
  87. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>my_functor
  88. </span><span class=special>{
  89. </span><span class=identifier>my_functor</span><span class=special>(</span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>& </span><span class=identifier>str_</span><span class=special>)
  90. </span><span class=special>: </span><span class=identifier>str</span><span class=special>(</span><span class=identifier>str_</span><span class=special>) </span><span class=special>{}
  91. </span><span class=keyword>void
  92. </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
  93. </span><span class=special>{
  94. </span><span class=identifier>str</span><span class=special>.</span><span class=identifier>assign</span><span class=special>(</span><span class=identifier>first</span><span class=special>, </span><span class=identifier>last</span><span class=special>);
  95. </span><span class=special>}
  96. </span><span class=identifier>std</span><span class=special>::</span><span class=identifier>string</span><span class=special>& </span><span class=identifier>str</span><span class=special>;
  97. </span><span class=special>};</span></font></code></pre>
  98. <h3>Full Example:</h3>
  99. <p>Here now is our calculator enhanced with semantic actions:</p>
  100. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>namespace
  101. </span><span class=special>{
  102. </span><span class=keyword>void </span><span class=identifier>do_int</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>str</span><span class=special>, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>* </span><span class=identifier>end</span><span class=special>)
  103. </span><span class=special>{
  104. </span><span class=identifier>string </span><span class=identifier>s</span><span class=special>(</span><span class=identifier>str</span><span class=special>, </span><span class=identifier>end</span><span class=special>);
  105. </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"PUSH(" </span><span class=special>&lt;&lt; </span><span class=identifier>s </span><span class=special>&lt;&lt; </span><span class=literal>')' </span><span class=special>&lt;&lt; </span><span class=identifier>endl</span><span class=special>;
  106. </span><span class=special>}
  107. </span><span class=keyword>void </span><span class=identifier>do_add</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>{ </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"ADD\n"</span><span class=special>; </span><span class=special>}
  108. </span><span class=keyword>void </span><span class=identifier>do_subt</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>{ </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"SUBTRACT\n"</span><span class=special>; </span><span class=special>}
  109. </span><span class=keyword>void </span><span class=identifier>do_mult</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>{ </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"MULTIPLY\n"</span><span class=special>; </span><span class=special>}
  110. </span><span class=keyword>void </span><span class=identifier>do_div</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>{ </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"DIVIDE\n"</span><span class=special>; </span><span class=special>}
  111. </span><span class=keyword>void </span><span class=identifier>do_neg</span><span class=special>(</span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*, </span><span class=keyword>char </span><span class=keyword>const</span><span class=special>*) </span><span class=special>{ </span><span class=identifier>cout </span><span class=special>&lt;&lt; </span><span class=string>"NEGATE\n"</span><span class=special>; </span><span class=special>}
  112. </span><span class=special>}</span></font></code></pre>
  113. <p>We augment our grammar with semantic actions:</p>
  114. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>calculator </span><span class=special>: </span><span class=keyword>public </span><span class=identifier>grammar</span><span class=special>&lt;</span><span class=identifier>calculator</span><span class=special>&gt;
  115. </span><span class=special>{
  116. </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;
  117. </span><span class=keyword>struct </span><span class=identifier>definition
  118. </span><span class=special>{
  119. </span><span class=identifier>definition</span><span class=special>(</span><span class=identifier>calculator </span><span class=keyword>const</span><span class=special>& </span><span class=identifier>self</span><span class=special>)
  120. </span><span class=special>{
  121. </span><span class=identifier>expression
  122. </span><span class=special>= </span><span class=identifier>term
  123. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=special>(</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>)[&</span><span class=identifier>do_add</span><span class=special>]
  124. </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>term</span><span class=special>)[&</span><span class=identifier>do_subt</span><span class=special>]
  125. </span><span class=special>)
  126. </span><span class=special>;
  127. </span><span class=identifier>term </span><span class=special>=
  128. </span><span class=identifier>factor
  129. </span><span class=special>&gt;&gt; </span><span class=special>*( </span><span class=special>(</span><span class=literal>'*' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>)[&</span><span class=identifier>do_mult</span><span class=special>]
  130. </span><span class=special>| </span><span class=special>(</span><span class=literal>'/' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>)[&</span><span class=identifier>do_div</span><span class=special>]
  131. </span><span class=special>)
  132. </span><span class=special>;
  133. </span><span class=identifier>factor
  134. </span><span class=special>= </span><span class=identifier>lexeme_d</span><span class=special>[(+</span><span class=identifier>digit_p</span><span class=special>)[&</span><span class=identifier>do_int</span><span class=special>]]
  135. </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>')'
  136. </span><span class=special>| </span><span class=special>(</span><span class=literal>'-' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>)[&</span><span class=identifier>do_neg</span><span class=special>]
  137. </span><span class=special>| </span><span class=special>(</span><span class=literal>'+' </span><span class=special>&gt;&gt; </span><span class=identifier>factor</span><span class=special>)
  138. </span><span class=special>;
  139. </span><span class=special>}
  140. </span><span class=identifier>rule</span><span class=special>&lt;</span><span class=identifier>ScannerT</span><span class=special>&gt; </span><span class=identifier>expression</span><span class=special>, </span><span class=identifier>term</span><span class=special>, </span><span class=identifier>factor</span><span class=special>;
  141. </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>&
  142. </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>expression</span><span class=special>; </span><span class=special>}
  143. </span><span class=special>};
  144. </span><span class=special>};</span></font></code></pre>
  145. <p>Feeding in the expression <tt>(-1 + 2) * (3 + -4)</tt>, for example, to the
  146. rule <tt>expression</tt> will produce the expected output:</p>
  147. <pre><code><span class=special>-</span><span class=number>1
  148. </span><span class=number>2
  149. </span><span class=identifier>ADD
  150. </span><span class=number>3
  151. </span><span class=special>-</span><span class=number>4
  152. </span><span class=identifier>ADD
  153. </span><span class=identifier>MULT</span></code></pre>
  154. <p>which, by the way, is the Reverse Polish Notation (RPN) of the given expression,
  155. reminiscent of some primitive calculators and the language Forth.</p>
  156. <p><img src="theme/lens.gif" width="15" height="16"> <a href="../example/fundamental/calc_plain.cpp">View
  157. the complete source code here</a>. This is part of the Spirit distribution.
  158. </p>
  159. <h2><a name="specialized_actions"></a>Specialized Actions</h2>
  160. <p>In general, semantic actions accept the first-last iterator pair. There are
  161. situations though where we might want to pass data in its processed form. A
  162. concrete example is the numeric parser. It is unwise to pass unprocessed data
  163. to a semantic action attached to a numeric parser and just throw away what has
  164. been parsed by the parser. We want to pass the actual parsed number.</p>
  165. <p>The function and functor signature of a semantic action varies depending on
  166. the parser where it is attached to. The following table lists the parsers that
  167. accept unique signatures.</p>
  168. <table width="80%" border="0" align="center">
  169. <tr>
  170. <td class="note_box"><img src="theme/note.gif" width="16" height="16"> Unless
  171. explicitly stated in the documentation of a specific parser type, parsers
  172. not included in the list by default expect the generic signature as explained
  173. above.</td>
  174. </tr>
  175. </table>
  176. <h3>Numeric Actions</h3>
  177. <p><b>Applies to:</b></p>
  178. <blockquote>
  179. <p><img src="theme/bullet.gif" width="13" height="13"> uint_p<br>
  180. <img src="theme/bullet.gif" width="13" height="13"> int_p<br>
  181. <img src="theme/bullet.gif" width="13" height="13"> ureal_p<br>
  182. <img src="theme/bullet.gif" width="13" height="13"> real_p</p>
  183. </blockquote>
  184. <p><b>Signature for functions:</b></p>
  185. <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>NumT </span><span class=identifier>val</span><span class=special>);</span></font></code></pre>
  186. <p><b>Signature for functors:</b> </p>
  187. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>ftor
  188. </span><span class=special>{
  189. </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>NumT </span><span class=identifier>val</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
  190. </span><span class=special>};</span></font></code></pre>
  191. <p>Where <tt>NumT</tt> is any primitive numeric type such as <tt>int</tt>, <tt>long</tt>,
  192. <tt>float</tt>, <tt>double</tt>, etc., or a user defined numeric type such as
  193. big_int. <tt>NumT</tt> is the same type used as template parameter to <tt>uint_p</tt>,
  194. <tt>int_p</tt>, <tt>ureal_p</tt> or <tt>real_p</tt>. The parsed number is passed
  195. into the function/functor.</p>
  196. <h3>Character Actions</h3>
  197. <p><b>Applies to:</b></p>
  198. <blockquote>
  199. <p><img src="theme/bullet.gif" width="13" height="13"> chlit, ch_p<br>
  200. <img src="theme/bullet.gif" width="13" height="13"> range, range_p<br>
  201. <img src="theme/bullet.gif" width="13" height="13"> anychar<br>
  202. <img src="theme/bullet.gif" width="13" height="13"> alnum, alpha<br>
  203. <img src="theme/bullet.gif" width="13" height="13"> cntrl, digit<br>
  204. <img src="theme/bullet.gif" width="13" height="13"> graph, lower<br>
  205. <img src="theme/bullet.gif" width="13" height="13"> print, punct<br>
  206. <img src="theme/bullet.gif" width="13" height="13"> space, upper<br>
  207. <img src="theme/bullet.gif" width="13" height="13"> xdigit</p>
  208. </blockquote>
  209. <p><b>Signature for functions:</b></p>
  210. <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>CharT </span><span class=identifier>ch</span><span class=special>);</span></font></code></pre>
  211. <p><b>Signature for functors:</b></p>
  212. <pre><code><font color="#000000"><span class=special> </span><span class=keyword>struct </span><span class=identifier>ftor
  213. </span><span class=special>{
  214. </span><span class=keyword>void </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>CharT </span><span class=identifier>ch</span><span class=special>) </span><span class=keyword>const</span><span class=special>;
  215. </span><span class=special>};</span></font></code></pre>
  216. <p>Where <tt>CharT</tt> is the value_type of the iterator used in parsing. A <tt>char
  217. const*</tt> iterator for example has a <tt>value_type</tt> of <tt>char</tt>.
  218. The matching character is passed into the function/functor.</p>
  219. <h2>Cascading Actions</h2>
  220. <p>Actions can be cascaded. Cascaded actions also inherit the function/functor
  221. interface of the original. For example:</p>
  222. <pre><code><font color="#000000"><span class=special> </span><span class=identifier>uint_p</span><span class=special>[</span><span class=identifier>fa</span><span class=special>][</span><span class=identifier>fb</span><span class=special>][</span><span class=identifier>fc</span><span class=special>]</span></font></code></pre>
  223. <p>Here, the functors <tt>fa</tt>, <tt>fb</tt> and <tt>fc</tt> all expect the
  224. signature <tt>void operator()(unsigned n) const</tt>.</p>
  225. <h2>Directives and Actions</h2>
  226. <p>Directives inherit the function/functor interface of the subject it is
  227. enclosing. Example:</p>
  228. <pre><code><font color="#000000"><span class=special> </span><span class=identifier>as_lower_d</span><span class=special>[</span><span class=identifier>ch_p</span><span class=special>(</span><span class=literal>'x'</span><span class=special>)][</span><span class=identifier>f</span><span class=special>]</span></font></code></pre>
  229. <p>Here, the functor <tt>f</tt> expects the signature <tt>void operator()(char
  230. ch) const</tt>, assuming that the iterator used is a <tt>char const*</tt>.</p>
  231. <table border="0">
  232. <tr>
  233. <td width="10"></td>
  234. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  235. <td width="30"><a href="subrules.html"><img src="theme/l_arr.gif" border="0"></a></td>
  236. <td width="30"><a href="indepth_the_parser.html"><img src="theme/r_arr.gif" border="0"></a></td>
  237. </tr>
  238. </table>
  239. <br>
  240. <hr size="1">
  241. <p class="copyright">Copyright &copy; 1998-2003 Joel de Guzman<br>
  242. <br>
  243. <font size="2">Use, modification and distribution is subject to the Boost Software
  244. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  245. http://www.boost.org/LICENSE_1_0.txt)</font></p>
  246. <p>&nbsp;</p>
  247. <p>&nbsp;</p>
  248. </body>
  249. </html>