subrule.qbk 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. [/==============================================================================
  2. Copyright (C) 2001-2011 Joel de Guzman
  3. Copyright (C) 2001-2011 Hartmut Kaiser
  4. Copyright (C) 2009 Francois Barel
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ===============================================================================/]
  8. [section:subrule Karma subrules]
  9. [heading Description]
  10. The __karma__ `subrule` is a component allowing to create a named generator, and
  11. to refer to it by name -- much like rules and grammars. It is in fact a fully
  12. static version of the rule.
  13. The strength of subrules is performance. Replacing some rules with subrules
  14. can make a generator slightly faster (see
  15. [link spirit_repository.karma_components.nonterminal.subrule.performance Performance]
  16. below for measurements). The reason is that subrules allow aggressive inlining
  17. by the C++ compiler, whereas the implementation of rules is based on a virtual
  18. function call which, depending on the compiler, can have some run-time overhead
  19. and stop inlining.
  20. The weaknesses of subrules are:
  21. * subrules can only be defined and used within the same generator expression. A
  22. subrule cannot be defined at one location, and then used in another location.
  23. * subrules put a massive strain on the C++ compiler. They increase compile
  24. times and memory usage during compilation, and also increase the risk of
  25. hitting compiler limits and/or bugs.
  26. [import ../../example/karma/calc2_ast_dump_sr.cpp]
  27. [calc2_ast_dump_sr_def]
  28. The example above can be found here: [@../../example/karma/calc2_ast_dump_sr.cpp]
  29. As shown in this code snippet (an extract from the calc2_ast_dump_sr example),
  30. subrules can be freely mixed with rules and grammars. Here, a group of
  31. 3 subrules (`ast_node`, `binary_node`, `unary_node`) is assigned to a rule (named
  32. `entry`). This means that parts of a generator can use subrules (typically
  33. the innermost, most performance-critical parts), whereas the rest can use
  34. rules and grammars.
  35. [heading Header]
  36. // forwards to <boost/spirit/repository/home/karma/nonterminal/subrule.hpp>
  37. #include <boost/spirit/repository/include/karma_subrule.hpp>
  38. [heading Synopsis (declaration)]
  39. subrule<ID, A1, A2> sr(name);
  40. [heading Parameters (declaration)]
  41. [table
  42. [[Parameter] [Description]]
  43. [[`ID`] [Required numeric argument. Gives the subrule
  44. a unique 'identification tag'.]]
  45. [[`A1`, `A2`] [Optional types, can be specified in any order.
  46. Can be one of 1. signature, 2. locals
  47. (see rules reference for more information on
  48. those parameters).
  49. Note that the delimiter type need not be specified
  50. in the parameters, unlike with grammars and rules.
  51. Subrules will automatically use the delimiter type
  52. which is in effect when they are invoked.]]
  53. [[`name`] [Optional string. Gives the subrule a name,
  54. useful for debugging and error handling.]]
  55. ]
  56. [heading Synopsis (usage)]
  57. Subrules are defined and used within groups, typically (and by convention)
  58. enclosed inside parentheses.
  59. // Group containing N subrules
  60. (
  61. sr1 = expr1
  62. , sr2 = expr2
  63. , ... // Any number of subrules
  64. }
  65. The IDs of all subrules defined within the same group must be different. It is
  66. an error to define several subrules with the same ID (or to define the same
  67. subrule multiple times) in the same group.
  68. // Auto-subrules and inherited attributes
  69. (
  70. srA %= exprA << srB << srC(c1, c2, ...) // Arguments to subrule srC
  71. , srB %= exprB
  72. , srC = exprC
  73. , ...
  74. )(a1, a2, ...) // Arguments to group, i.e. to start subrule srA
  75. [heading Parameters (usage)]
  76. [table
  77. [[Parameter] [Description]]
  78. [[`sr1`, `sr2`] [Subrules with different IDs.]]
  79. [[`expr1`, `expr2`] [Generator expressions. Can include `sr1` and `sr2`,
  80. as well as any other valid generator expressions.]]
  81. [[`srA`] [Subrule with a synthesized attribute and inherited
  82. attributes.]]
  83. [[`srB`] [Subrule with a synthesized attribute.]]
  84. [[`srC`] [Subrule with inherited attributes.]]
  85. [[`exprA`, `exprB`, `exprC`]
  86. [Generator expressions.]]
  87. [[`a1`, `a2`] [Arguments passed to the subrule group. They are
  88. passed as inherited attributes to the group's
  89. start subrule, `srA`.]]
  90. [[`c1`, `c2`] [Arguments passed as inherited attributes to
  91. subrule `srC`.]]
  92. ]
  93. [heading Groups]
  94. A subrule group (a set of subrule definitions) is a generator, which can be
  95. used anywhere in a generator expression (in assignments to rules, as well as
  96. directly in arguments to functions such as `generate`).
  97. In a group, generation proceeds from the start subrule, which is the first
  98. (topmost) subrule defined in that group. In the two groups in the synopsis
  99. above, `sr1` and `srA` are the start subrules respectively -- for example
  100. when the first subrule group is called forth, the `sr1` subrule is called.
  101. A subrule can only be used in a group which defines it. Groups can be viewed
  102. as scopes: a definition of a subrule is limited to its enclosing group.
  103. rule<outiter_type> r1, r2, r3;
  104. subrule<1> sr1;
  105. subrule<2> sr2;
  106. r1 =
  107. ( sr1 = 'a' << space ) // First group in r1.
  108. << ( sr2 = +sr1 ) // Second group in r1.
  109. // ^^^
  110. // DOES NOT COMPILE: sr1 is not defined in this
  111. // second group, it cannot be used here (its
  112. // previous definition is out of scope).
  113. ;
  114. r2 =
  115. ( sr1 = 'a' << space ) // Only group in r2.
  116. << sr1
  117. // ^^^
  118. // DOES NOT COMPILE: not in a subrule group,
  119. // sr1 cannot be used here (here too, its
  120. // previous definition is out of scope).
  121. ;
  122. r3 =
  123. ( sr1 = space << 'x' ) // Another group. The same subrule `sr1`
  124. // can have another, independent
  125. // definition in this group.
  126. ;
  127. [heading Attributes]
  128. A subrule has the same behavior as a rule with respect to attributes. In
  129. particular:
  130. * the type of its synthesized attribute is the one specified in the
  131. subrule's signature, if any. Otherwise it is `unused_type`.
  132. * the types of its inherited attributes are the ones specified in the
  133. subrule's signature, if any. Otherwise the subrule has no inherited
  134. attributes.
  135. * an auto-subrule can be defined by assigning it with the `%=` syntax.
  136. In this case, the subrule's synthesized attribute is automatically
  137. propagated to the RHS generator's attribute.
  138. * the Phoenix placeholders `_val`, `_r1`, `_r2`, ... are available to
  139. refer to the subrule's synthesized and inherited attributes, if present.
  140. [heading Locals]
  141. A subrule has the same behavior as a rule with respect to locals. In
  142. particular, the Phoenix placeholders `_a`, `_b`, ... are available to
  143. refer to the subrule's locals, if present.
  144. [heading Example]
  145. [import ../../example/karma/mini_xml_karma_sr.cpp]
  146. Some includes:
  147. [mini_xml_karma_sr_includes]
  148. Some using declarations:
  149. [mini_xml_karma_sr_using]
  150. A grammar containing only one rule, defined with a group of 2 subrules:
  151. [mini_xml_karma_sr_grammar]
  152. The definitions of the `mini_xml` and `mini_xml_node` data structures
  153. are not shown here. The full example above can be found here:
  154. [@../../example/karma/mini_xml_karma_sr.cpp]
  155. [heading Performance]
  156. For comparison of run-time and compile-time performance when using subrules,
  157. please see the
  158. [link spirit_repository.qi_components.nonterminal.subrule.performance Performance]
  159. section of __qi__ subrules (the implementation of __karma__ and __qi__ subrules
  160. is very similar, so performance is very similar too).
  161. [heading Notes]
  162. Subrules push the C++ compiler hard. A group of subrules is a single C++
  163. expression. Current C++ compilers cannot handle very complex expressions very
  164. well. One restricting factor is the typical compiler's limit on template
  165. recursion depth. Some, but not all, compilers allow this limit to be
  166. configured.
  167. g++'s maximum can be set using a compiler flag: `-ftemplate-depth`. Set this
  168. appropriately if you use relatively complex subrules.
  169. [endsect]