1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<html> 3<head> 4<title>Refactoring Parsers</title> 5<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 6<link href="theme/style.css" rel="stylesheet" type="text/css"> 7</head> 8 9<body> 10<table width="100%" border="0" background="theme/bkd2.gif" cellspacing="2"> 11 <tr> 12 <td width="10"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b> </b></font></td> 13 <td width="85%"> <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Refactoring Parsers</b></font></td> 14 <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" width="112" height="48" align="right" border="0"></a></td> 15 </tr> 16</table> 17<br> 18<table border="0"> 19 <tr> 20 <td width="10"></td> 21 <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> 22 <td width="30"><a href="functor_parser.html"><img src="theme/l_arr.gif" border="0"></a></td> 23 <td width="30"><a href="regular_expression_parser.html"><img src="theme/r_arr.gif" border="0"></a></td> 24 </tr> 25</table> 26<p><a name="refactoring_parsers"></a>There are three types of Refactoring Parsers 27 implemented right now, which help to abstract common parser refactoring tasks. 28 Parser refactoring means, that a concrete parser construct is replaced (refactored) 29 by another very similar parser construct. Two of the Refactoring Parsers described 30 here (<tt>refactor_unary_parser</tt> and <tt>refactor_action_parser</tt>) are 31 introduced to allow a simple and more expressive notation while using <a href="confix.html">Confix 32 Parsers</a> and <a href="list_parsers.html">List Parsers</a>. The third Refactoring 33 Parser (<tt>attach_action_parser</tt>) is implemented to abstract some functionality 34 required for the Grouping Parser. Nevertheless 35 these Refactoring Parsers may help in solving other complex parsing tasks too.</p> 36<h3>Refactoring unary parsers</h3> 37<p>The <tt>refactor_unary_d</tt> parser generator, which should be used to generate 38 a unary refactoring parser, transforms a construct of the following type</p> 39<pre><code> <span class=identifier>refactor_unary_d</span><span class=special>[*</span><span class=identifier>some_parser </span><span class=special>- </span><span class=identifier>another_parser</span><span class=special>]</span></code></pre> 40<p>to </p> 41<pre><code> <span class=special>*(</span><span class=identifier>some_parser</span> <span class=special>- </span><span class=identifier>another_parser</span><span class=special>)</span></code></pre> 42<blockquote> 43 <p>where <tt>refactor_unary_d</tt> is a predefined object of the parser generator 44 struct <tt>refactor_unary_gen<></tt></p> 45</blockquote> 46<p>The <tt>refactor_unary_d</tt> parser generator generates a new parser as shown 47 above, only if the original construct is an auxiliary binary parser (here the 48 difference parser) and the left operand of this binary parser is an auxiliary 49 unary parser (here the kleene star operator). If the original parser isn't a 50 binary parser the compilation will fail. If the left operand isn't an unary 51 parser, no refactoring will take place.</p> 52<h3>Refactoring action parsers</h3> 53<p>The <tt>refactor_action_d</tt> parser generator, which should be used to generate 54 an action refactoring parser, transforms a construct of the following type</p> 55<pre><code> <span class=identifier>refactor_action_d</span><span class=special>[</span><span class=identifier>some_parser</span><span class=special>[</span><span class=identifier>some_actor</span><span class=special>] </span><span class=special>- </span><span class=identifier>another_parser</span><span class=special>]</span></code></pre> 56<p>to </p> 57<pre><code> <span class=special>(</span><span class=identifier>some_parser </span><span class=special>- </span><span class=identifier>another_parser</span><span class=special>)[</span><span class=identifier>some_actor</span><span class=special>]</span></code></pre> 58<blockquote> 59 <p>where <tt>refactor_action_d</tt> is a predefined object of the parser generator 60 struct <tt>refactor_action_gen<></tt></p> 61</blockquote> 62<p>The <tt>refactor_action_d</tt> parser generator generates a new parser as shown 63 above, only if the original construct is an auxiliary binary parser (here the 64 difference parser) and the left operand of this binary parser is an auxiliary 65 parser generated by an attached semantic action. If the original parser isn't 66 a binary parser the compilation will fail. If the left operand isn't an action 67 parser, no refactoring will take place.</p> 68<h3>Attach action refactoring</h3> 69<p>The <tt>attach_action_d</tt> parser generator, which should be used to generate 70 an attach action refactoring parser, transforms a construct of the following 71 type</p> 72<pre><code> <span class=identifier>attach_action_d</span><span class=special>[</span><span class=identifier>(some_parser</span> <span class=special>>> </span><span class=identifier>another_parser</span>)<span class=special>[</span><span class=identifier>some_actor</span><span class=special>]</span><span class=special>]</span></code></pre> 73<p>to </p> 74<pre><code> <span class=identifier>some_parser</span><span class=special>[</span><span class=identifier>some_actor</span><span class=special>]</span><span class=identifier> </span><span class=special>>> </span><span class=identifier>another_parser</span><span class=special>[</span><span class=identifier>some_actor</span><span class=special>]</span></code></pre> 75<blockquote> 76 <p>where <tt>attach_action_d</tt> is a predefined object of the parser generator 77 struct <tt>attach_action_gen<></tt></p> 78</blockquote> 79 80<p>The <tt>attach_action_d</tt> parser generator generates a new parser as shown 81 above, only if the original construct is an auxiliary action parser and the 82 parser to it this action is attached is an auxiliary binary parser (here the 83 sequence parser). If the original parser isn't a action parser the compilation 84 will fail. If the parser to which the action is attached isn't an binary parser, 85 no refactoring will take place.</p> 86<h3>Nested refactoring</h3> 87<p>Sometimes it is required to nest different types of refactoring, i.e. to transform 88 constructs like</p> 89<pre><code> <span class=special>(*</span><span class=identifier>some_parser</span><span class=special>)[</span><span class=identifier>some_actor</span><span class=special>] </span><span class=special>- </span><span class=identifier>another_parser</span></code></pre> 90<p>to </p> 91<pre><code> <span class=special>(*(</span><span class=identifier>some_parser </span><span class=special>- </span><span class=identifier>another_parser</span><span class=special>))[</span><span class=identifier>some_actor</span><span class=special>]</span></code></pre> 92<p>To simplify the construction of such nested refactoring parsers the <tt>refactor_unary_gen<></tt> 93 and <tt>refactor_action_gen<></tt> both can take another refactoring parser 94 generator type as their respective template parameter. For instance, to construct 95 a refactoring parser generator for the mentioned nested transformation we should 96 write:</p> 97<pre><span class=special> </span><span class=keyword>typedef </span><span class=identifier>refactor_action_gen</span><span class=special><</span><span class=identifier>refactor_unary_gen</span><span class=special><> </span><span class=special>> </span><span class=identifier>refactor_t</span><span class=special>; 98 </span><span class=keyword>const </span><span class=identifier>refactor_t </span><span class=identifier>refactor_nested_d </span><span class=special>= </span><span class=identifier>refactor_t</span><span class=special>(</span><span class=identifier>refactor_unary_d</span><span class=special>);</span></pre> 99<p>Now we could use it as follows to get the required result:</p> 100<pre><code><font color="#0000FF"> </font><span class=identifier>refactor_nested_d</span><span class=special>[(*</span><span class=identifier>some_parser</span><span class=special>)[</span><span class=identifier>some_actor</span><span class=special>] </span><span class=special>- </span><span class=identifier>another_parser</span><span class=special>]</span></code></pre> 101<p>An empty template parameter means not to nest this particular refactoring parser. 102 The default template parameter is <tt>non_nesting_refactoring</tt>, a predefined 103 helper structure for inhibiting nesting. Sometimes it is required to nest a 104 particular refactoring parser with itself. This is achieved by providing the 105 predefined helper structure <tt>self_nested_refactoring</tt> as the template 106 parameter to the corresponding refactoring parser generator template.</p> 107<p><img src="theme/lens.gif" width="15" height="16"> See <a href="../example/fundamental/refactoring.cpp">refactoring.cpp</a> for a compilable example. This is part of the Spirit distribution. </p> 108<table border="0"> 109 <tr> 110 <td width="10"></td> 111 <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td> 112 <td width="30"><a href="functor_parser.html"><img src="theme/l_arr.gif" border="0"></a></td> 113 <td width="30"><a href="regular_expression_parser.html"><img src="theme/r_arr.gif" border="0"></a></td> 114 </tr> 115</table> 116<br> 117<hr size="1"> 118<p class="copyright">Copyright © 2001-2003 Hartmut Kaiser<br> 119 <br> 120 <font size="2">Use, modification and distribution is subject to the Boost Software 121 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 122 http://www.boost.org/LICENSE_1_0.txt)</font></p> 123<p> </p> 124</body> 125</html> 126