PageRenderTime 74ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/fparsec/main/Doc/html/reference/operatorprecedenceparser.html

http://github.com/sandersn/fing
HTML | 782 lines | 754 code | 22 blank | 6 comment | 0 complexity | 459a17f202da8ddb7f480b72c2e6fbd7 MD5 | raw file
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  5. <title>FParsec.OperatorPrecedenceParser</title>
  6. <link rel="stylesheet" type="text/css" media="all" href="../css/style.css" />
  7. <link rel="stylesheet" type="text/css" media="screen" href="../css/screen-sidebar.css" title="Sidebar" />
  8. <link rel="alternate stylesheet" type="text/css" media="screen" href="../css/screen-no-sidebar.css" title="No sidebar" />
  9. <!--[if IE]>
  10. <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie.css" />
  11. <![endif]-->
  12. <!--[if IE 6]>
  13. <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie6.css" />
  14. <![endif]-->
  15. <link rel="stylesheet" type="text/css" media="print" href="../css/print.css" />
  16. </head>
  17. <body>
  18. <div id="fixed-layer">
  19. <div id="fixed-wrapper">
  20. <div id="sidebar">
  21. <div id="breadcrumbs-dummy"><span class="breadcrumbs">&nbsp;</span></div>
  22. <div id="nav-tree">
  23. <table class="nav n1">
  24. <tbody class="nav-open n1">
  25. <tr class="nav-entry n1 _1">
  26. <td class="nav-number n1"></td>
  27. <td class="nav-title n1"><a href="../index.html">FParsec Documentation</a></td>
  28. </tr>
  29. <tr class="nav-sub-entries n1 _1">
  30. <td class="nav-sub-entries-number n1"></td>
  31. <td class="nav-sub-entries n1">
  32. <table class="nav n2">
  33. <tbody class="nav-before-open n2">
  34. <tr class="nav-entry n2 _1">
  35. <td class="nav-number n2"><a href="../tutorial.html"><span class="section-number">1</span><span class="nav-space"></span></a></td>
  36. <td class="nav-title n2"><a href="../tutorial.html">Tutorial</a></td>
  37. </tr>
  38. </tbody>
  39. <tbody class="nav-open n2">
  40. <tr class="nav-entry n2 _2">
  41. <td class="nav-number n2"><a href="index.html"><span class="section-number">2</span><span class="nav-space"></span></a></td>
  42. <td class="nav-title n2"><a href="index.html">Reference</a></td>
  43. </tr>
  44. <tr class="nav-sub-entries n2 _2">
  45. <td class="nav-sub-entries-number n2"></td>
  46. <td class="nav-sub-entries n2">
  47. <table class="nav n3">
  48. <tbody class="nav-before-open n3">
  49. <tr class="nav-entry n3 _1">
  50. <td class="nav-number n3"><a href="parser-overview.html"><span class="section-number">1</span><span class="nav-space"></span></a></td>
  51. <td class="nav-title n3"><a href="parser-overview.html">Parser overview</a></td>
  52. </tr>
  53. <tr class="nav-entry n3 _2">
  54. <td class="nav-number n3"><a href="primitives.html"><span class="section-number">2</span><span class="nav-space"></span></a></td>
  55. <td class="nav-title n3"><a href="primitives.html">FParsec.Primitives</a></td>
  56. </tr>
  57. <tr class="nav-entry n3 _3">
  58. <td class="nav-number n3"><a href="charparsers.html"><span class="section-number">3</span><span class="nav-space"></span></a></td>
  59. <td class="nav-title n3"><a href="charparsers.html">FParsec.CharParsers</a></td>
  60. </tr>
  61. </tbody>
  62. <tbody class="nav-open selected n3">
  63. <tr class="nav-entry selected n3 _4">
  64. <td class="nav-number selected n3"><a href="#"><span class="section-number">4</span><span class="nav-space"></span></a></td>
  65. <td class="nav-title selected n3"><a href="#">FParsec.OperatorPrecedenceParser</a></td>
  66. </tr>
  67. <tr class="nav-sub-entries selected n3 _4">
  68. <td class="nav-sub-entries-number selected n3"></td>
  69. <td class="nav-sub-entries selected n3">
  70. <table class="nav n4">
  71. <tbody class="nav-before-open n4">
  72. <tr class="nav-entry n4 _1">
  73. <td class="nav-number n4"><a href="#interface"><span class="section-number">1</span><span class="nav-space"></span></a></td>
  74. <td class="nav-title n4"><a href="#interface">Interface</a></td>
  75. </tr>
  76. <tr class="nav-entry n4 _2">
  77. <td class="nav-number n4"><a href="#members"><span class="section-number">2</span><span class="nav-space"></span></a></td>
  78. <td class="nav-title n4"><a href="#members">Members</a></td>
  79. </tr>
  80. </tbody>
  81. </table>
  82. </td>
  83. </tr>
  84. </tbody>
  85. <tbody class="nav-after-open n3">
  86. <tr class="nav-entry n3 _5">
  87. <td class="nav-number n3"><a href="error.html"><span class="section-number">5</span><span class="nav-space"></span></a></td>
  88. <td class="nav-title n3"><a href="error.html">FParsec.Error</a></td>
  89. </tr>
  90. <tr class="nav-entry n3 _6">
  91. <td class="nav-number n3"><a href="state.html"><span class="section-number">6</span><span class="nav-space"></span></a></td>
  92. <td class="nav-title n3"><a href="state.html">FParsec.State</a></td>
  93. </tr>
  94. <tr class="nav-entry n3 _7">
  95. <td class="nav-number n3"><a href="position.html"><span class="section-number">7</span><span class="nav-space"></span></a></td>
  96. <td class="nav-title n3"><a href="position.html">FParsec.Position</a></td>
  97. </tr>
  98. <tr class="nav-entry n3 _8">
  99. <td class="nav-number n3"><a href="charstream.html"><span class="section-number">8</span><span class="nav-space"></span></a></td>
  100. <td class="nav-title n3"><a href="charstream.html">FParsec.CharStream</a></td>
  101. </tr>
  102. </tbody>
  103. </table>
  104. </td>
  105. </tr>
  106. </tbody>
  107. </table>
  108. </td>
  109. </tr>
  110. </tbody>
  111. </table>
  112. </div>
  113. </div>
  114. </div>
  115. </div>
  116. <div id="wrapper">
  117. <div id="main">
  118. <div id="main-content">
  119. <div id="breadcrumbs">
  120. <span class="breadcrumbs">
  121. <span id="breadcrumbs-parents"><a href="../index.html">FParsec Documentation</a><span class="breadcrumbs-sep"> > </span><a href="index.html">Reference</a></span><span class="breadcrumbs-sep"> > </span>FParsec.OperatorPrecedenceParser
  122. </span>
  123. </div>
  124. <div class="section s2">
  125. <h1 class="title h2"><span class="section-number">2.4</span> FParsec.OperatorPrecedenceParser</h1>
  126. <div class="intro i2">
  127. <p class="para _1">
  128. This module defines the <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  129. class="ci">OperatorPrecedenceParser</span></a></code> class.
  130. </p>
  131. </div>
  132. <div id="interface" class="section s3">
  133. <h2 class="title h3"><span class="section-number">2.4.1</span> Interface</h2>
  134. <div class="intro i3">
  135. <div class="para _1">
  136. <pre class="code fsharp"><span class="ck">module</span> <span class="ci">FParsec</span><span class="cm">.</span><span class="ci">OperatorPrecedenceParser</span>
  137. <span class="ck">open</span> <a href="primitives.html"><span class="ci">FParsec</span><span class="cm">.</span><span class="ci">Primitives</span></a>
  138. <span class="ck">type</span> <a id="interface.Assoc:B:" href="#members.Assoc"><span class="interface-member-marker"><span class="ci">Assoc</span></span></a> <span class="cp">=</span> <span class="ci">None</span> <span class="cp">=</span> <span class="cn">0</span>
  139. <span class="cp">|</span> <span class="ci">Left</span> <span class="cp">=</span> <span class="cn">1</span>
  140. <span class="cp">|</span> <span class="ci">Right</span> <span class="cp">=</span> <span class="cn">2</span>
  141. <span class="cp">[&lt;</span><span class="ci">ReferenceEquality</span><span class="cp">&gt;]</span>
  142. <span class="ck">type</span> <a id="interface.PrecedenceParserOp:B:" href="#members.PrecedenceParserOp"><span class="interface-member-marker"><span class="ci">PrecedenceParserOp</span></span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">=</span>
  143. <span class="clc"><span class="left-delimiter">//</span> Op(opString, whitespaceParser, precedence, associativity, f)</span>
  144. <span class="cp">|</span> <a id="interface.PrefixOp:B:" href="#members.PrefixOp"><span class="interface-member-marker"><span class="ci">PrefixOp</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  145. <span class="cp">|</span> <a id="interface.PostfixOp:B:" href="#members.PostfixOp"><span class="interface-member-marker"><span class="ci">PostfixOp</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  146. <span class="cp">|</span> <a id="interface.InfixOp:B:" href="#members.InfixOp"><span class="interface-member-marker"><span class="ci">InfixOp</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  147. <span class="cp">|</span> <a id="interface.TernaryOp:B:" href="#members.TernaryOp"><span class="interface-member-marker"><span class="ci">TernaryOp</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  148. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  149. <span class="cp">|</span> <a id="interface.PrefixOp:39::B:" href="#members.PrefixOp:39:"><span class="interface-member-marker"><span class="ci">PrefixOp'</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  150. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  151. <span class="cp">|</span> <a id="interface.PostfixOp:39::B:" href="#members.PostfixOp:39:"><span class="interface-member-marker"><span class="ci">PostfixOp'</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  152. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  153. <span class="cp">|</span> <a id="interface.InfixOp:39::B:" href="#members.InfixOp:39:"><span class="interface-member-marker"><span class="ci">InfixOp'</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  154. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  155. <span class="cp">|</span> <a id="interface.TernaryOp:39::B:" href="#members.TernaryOp:39:"><span class="interface-member-marker"><span class="ci">TernaryOp'</span></span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  156. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a>
  157. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  158. <span class="ck">with</span>
  159. <span class="ck">override</span> <span class="ci">ToString</span><span class="cp">:</span> <span class="ci">unit</span> <span class="cr">-&gt;</span> <span class="ci">string</span>
  160. <span class="ck">type</span> <a id="interface.OperatorPrecedenceParser:B:" href="#members.OperatorPrecedenceParser"><span class="interface-member-marker"><span class="ci">OperatorPrecedenceParser</span></span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="co">=</span>
  161. <a id="interface.new:B:" href="#members.new"><span class="interface-member-marker"><span class="ck">new</span></span></a><span class="cp">:</span> <span class="cp">?</span><span class="ci">ops</span><span class="cp">:</span><span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">OperatorPrecedenceParser</span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  162. <span class="ck">member</span> <a id="interface.ExpressionParser:B:" href="#members.ExpressionParser"><span class="interface-member-marker"><span class="ci">ExpressionParser</span></span></a><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  163. <span class="ck">member</span> <a id="interface.TermParser:B:" href="#members.TermParser"><span class="interface-member-marker"><span class="ci">TermParser</span></span></a><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span> <span class="ctv">'u</span><span class="cp">&gt;</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  164. <span class="ck">member</span> <a id="interface.OperatorConflictHandler:B:" href="#members.OperatorConflictHandler"><span class="interface-member-marker"><span class="ci">OperatorConflictHandler</span></span></a><span class="cp">:</span> <span class="cp">(</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  165. <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  166. <span class="cr">-&gt;</span> <span class="ci">string</span><span class="cp">)</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  167. <span class="ck">member</span> <a id="interface.AddOperator:B:" href="#members.AddOperator"><span class="interface-member-marker"><span class="ci">AddOperator</span></span></a><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  168. <span class="ck">member</span> <a id="interface.AddOperators:B:" href="#members.AddOperators"><span class="interface-member-marker"><span class="ci">AddOperators</span></span></a><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  169. <span class="ck">member</span> <a id="interface.RemoveOperator:B:" href="#members.RemoveOperator"><span class="interface-member-marker"><span class="ci">RemoveOperator</span></span></a><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  170. <span class="ck">member</span> <a id="interface.RemoveInfixOp:B:" href="#members.RemoveInfixOp"><span class="interface-member-marker"><span class="ci">RemoveInfixOp</span></span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  171. <span class="ck">member</span> <a id="interface.RemovePrefixOp:B:" href="#members.RemovePrefixOp"><span class="interface-member-marker"><span class="ci">RemovePrefixOp</span></span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  172. <span class="ck">member</span> <a id="interface.RemovePostfixOp:B:" href="#members.RemovePostfixOp"><span class="interface-member-marker"><span class="ci">RemovePostfixOp</span></span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  173. <span class="ck">member</span> <a id="interface.RemoveTernaryOp:B:" href="#members.RemoveTernaryOp"><span class="interface-member-marker"><span class="ci">RemoveTernaryOp</span></span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  174. <span class="ck">member</span> <a id="interface.Operators:B:" href="#members.Operators"><span class="interface-member-marker"><span class="ci">Operators</span></span></a><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span>
  175. </pre>
  176. </div>
  177. </div>
  178. </div>
  179. <div id="members" class="section s3">
  180. <h2 class="title h3"><span class="section-number">2.4.2</span> Members</h2>
  181. <div class="intro i3">
  182. <div class="para _1">
  183. <div class="interface-members">
  184. <div class="interface-member _1" id="members.Assoc">
  185. <div class="interface-member-code">
  186. <a class="interface-member-backlink" href="#interface.Assoc:B:"></a>
  187. <pre class="code fsharp"><span class="ck">type</span> <span class="interface-member-marker"><span class="ci">Assoc</span></span></pre>
  188. </div>
  189. <div class="interface-member-description">
  190. <p class="para _1">Represents the associativity of infix operators.</p>
  191. <div class="para _2">
  192. <pre class="code fsharp"><span class="ck">type</span> <span class="ci">Assoc</span> <span class="cp">=</span> <span class="ci">None</span> <span class="cp">=</span> <span class="cn">0</span>
  193. <span class="cp">|</span> <span class="ci">Left</span> <span class="cp">=</span> <span class="cn">1</span>
  194. <span class="cp">|</span> <span class="ci">Right</span> <span class="cp">=</span> <span class="cn">2</span>
  195. </pre>
  196. </div>
  197. </div>
  198. </div>
  199. <div class="interface-member _2" id="members.PrecedenceParserOp">
  200. <div class="interface-member-code">
  201. <a class="interface-member-backlink" href="#interface.PrecedenceParserOp:B:"></a>
  202. <pre class="code fsharp"><span class="ck">type</span> <span class="interface-member-marker"><span class="ci">PrecedenceParserOp</span></span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></pre>
  203. </div>
  204. <div class="interface-member-description">
  205. <p class="para _1">
  206. This union type represents an operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  207. class="ci">OperatorPrecedenceParser</span></a></code> (OPP).
  208. </p>
  209. <div class="para _2">
  210. <pre class="code fsharp"><span class="cp">[&lt;</span><span class="ci">ReferenceEquality</span><span class="cp">&gt;]</span>
  211. <span class="ck">type</span> <span class="ci">PrecenceParserOp</span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span> <span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">=</span>
  212. <span class="clc"><span class="left-delimiter">//</span> Op(opString, whitespaceParser, precedence, associativity, f)</span>
  213. <span class="cp">|</span> <a href="#members.PrefixOp"><span class="ci">PrefixOp</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  214. <span class="cp">|</span> <a href="#members.PostfixOp"><span class="ci">PostfixOp</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  215. <span class="cp">|</span> <a href="#members.InfixOp"><span class="ci">InfixOp</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  216. <span class="cp">|</span> <a href="#members.TernaryOp"><span class="ci">TernaryOp</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  217. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  218. <span class="cp">|</span> <a href="#members.PrefixOp:39:"><span class="ci">PrefixOp'</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span>
  219. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  220. <span class="cp">|</span> <a href="#members.PostfixOp:39:"><span class="ci">PostfixOp'</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span>
  221. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  222. <span class="cp">|</span> <a href="#members.InfixOp:39:"><span class="ci">InfixOp'</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a>
  223. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  224. <span class="cp">|</span> <a href="#members.TernaryOp:39:"><span class="ci">TernaryOp'</span></a> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  225. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a>
  226. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  227. <span class="ck">with</span>
  228. <span class="ck">override</span> <span class="ci">ToString</span><span class="cp">:</span> <span class="ci">unit</span> <span class="cr">-&gt;</span> <span class="ci">string</span>
  229. </pre>
  230. </div>
  231. <p class="para _3">
  232. Four types of operators are supported: binary infix (e.g. &#x201C;1 + 1&#x201D;), unary prefix (e.g. &#x201C;1&#x201D;), unary postfix (e.g.
  233. &#x201C;1++&#x201D;) and Cstyle ternary operators (e.g. &#x201C;x &gt; 0 ? 1 : 2&#x201D;).
  234. </p>
  235. <p class="para _4">
  236. Each operator is defined by an operator string, a trailing whitespace parser, a precedence level, an associativity value and a function that
  237. is applied after the expression is parsed. Ternary operators require a string and associated whitespace parser for each of the two operator
  238. parts.
  239. </p>
  240. <p class="para _5">
  241. While infix operators can be left, right and nonassociative (see the <code class="fsharp"><a href="#members.Assoc"><span
  242. class="ci">Assoc</span></a></code> type), prefix and postfix operators can only be associative (<code class="fsharp"><span
  243. class="cb">true</span></code>) or nonassociative (<code class="fsharp"><span class="cb">false</span></code>). See below for details on <a
  244. href="#members.precedence-associativity">how precedence and associativity influence the operator precedence parser</a>.
  245. </p>
  246. <p class="para _6">
  247. After an OPP instance parsed a subexpression it will call the function given as the last operator argument to map the term(s) belonging to
  248. the operator to a new term. Often this function will be used to construct AST nodes or to directly transform terminal values.
  249. </p>
  250. <p class="para _7">
  251. The only difference between the constructors with and without the trailing ' is the signature of their function arguments. The functions of
  252. the '‐constructors are called with an additional parameter: the parser state as captured immediately before the operator string was parsed.
  253. This is for example useful if you want to annotate your AST nodes with the position of the operators in the input.
  254. </p>
  255. <p class="para _8">
  256. The string and the whitespace parser determine the textual representation of an operator. If the OPP encounters the operator string in the
  257. input, it will apply the whitespace parser directly after the operator string. If the whitespace parser succeeds, the operator will be
  258. accepted. If the whitespace parser fails after consuming input, the OPP will itself fail with this error. If the whitespace parser fails
  259. without consuming input, the OPP will backtrack to before the operator string and will not try to parse any other operator at this location.
  260. This behaviour can be exploited to conditionally accept an operator depending on the input following the operator string. For example, the
  261. whitespace parser definition in <code class="fsharp"><a href="#members.PrefixOp"><span class="ci">PrefixOp</span></a><span
  262. class="cp">(</span><span class="cs"><span class="left-delimiter">"</span>not<span class="right-delimiter">"</span></span><span
  263. class="cp">,</span> <a href="primitives.html#members.notFollowedBy"><span class="ci">notFollowedBy</span></a> <a
  264. href="charparsers.html#members.letter"><span class="ci">letter</span></a> <a href="primitives.html#members.:62::62::.:"><span
  265. class="co">&gt;&gt;.</span></a> <a href="charparsers.html#members.spaces"><span class="ci">spaces</span></a><span class="cp">,</span> <span
  266. class="cn">1</span><span class="cp">,</span> <span class="cb">true</span><span class="cp">,</span> <span class="ck">fun</span> <span
  267. class="ci">x</span> <span class="cr">-&gt;</span> <span class="ci">not</span> <span class="ci">x</span><span class="cp">)</span></code> will
  268. ensure that the <code class="fsharp"><span class="cs"><span class="left-delimiter">"</span>not<span
  269. class="right-delimiter">"</span></span></code> in <code class="fsharp"><span class="cs"><span
  270. class="left-delimiter">"</span>notAnOperator<span class="right-delimiter">"</span></span></code> can not be parsed as an operator.
  271. </p>
  272. <p class="para _9">
  273. You can configure an OPP instance to support a prefix operator with the same string as the (first) string of an infix, postfix or ternary
  274. operator. However, no two prefix operators and no two infix, postfix or ternary operators can have the same (first) string. The second string
  275. of a ternary operator can not be used for any other operator at the same time.
  276. </p>
  277. <p class="para _0">
  278. Note that the OPP will parse operators greedily. For example, if you define an operator with the string <code class="fsharp"><span
  279. class="cs"><span class="left-delimiter">"</span>-<span class="right-delimiter">"</span></span></code> and one with the string <code
  280. class="fsharp"><span class="cs"><span class="left-delimiter">"</span>--<span class="right-delimiter">"</span></span></code> then <code
  281. class="fsharp"><span class="co">--</span></code> in the input will always be parsed as a <code class="fsharp"><span
  282. class="co">--</span></code> operator never as two successive <code class="fsharp"><span class="co">-</span></code> operators, irrespective of
  283. the types of the involved operators.
  284. </p>
  285. <div class="para _1">
  286. <p>
  287. <code class="fsharp"><span class="ci">PrecenceParserOp</span><span class="cp">&lt;</span><span class="ctv">'a</span><span
  288. class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></code> has the following union cases:
  289. </p>
  290. <div class="interface-members">
  291. <div class="interface-member _1" id="members.PrefixOp">
  292. <div class="interface-member-code">
  293. <a class="interface-member-backlink" href="#interface.PrefixOp:B:"></a>
  294. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">PrefixOp</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  295. </pre>
  296. </div>
  297. <div class="interface-member-description">
  298. <p class="para _1">
  299. <code class="fsharp"><span class="ci">PrefixOp</span><span class="cp">(</span><span class="ci">opStr</span><span
  300. class="cp">,</span> <span class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span
  301. class="cp">,</span> <span class="ci">isAssoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  302. represents a prefix operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  303. class="ci">OperatorPrecedenceParser</span></a></code>.
  304. </p>
  305. </div>
  306. </div>
  307. <div class="interface-member _2" id="members.PostfixOp">
  308. <div class="interface-member-code">
  309. <a class="interface-member-backlink" href="#interface.PostfixOp:B:"></a>
  310. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">PostfixOp</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  311. </pre>
  312. </div>
  313. <div class="interface-member-description">
  314. <p class="para _1">
  315. <code class="fsharp"><span class="ci">PostfixOp</span><span class="cp">(</span><span class="ci">opStr</span><span
  316. class="cp">,</span> <span class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span
  317. class="cp">,</span> <span class="ci">isAssoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  318. represents a postfix operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  319. class="ci">OperatorPrecedenceParser</span></a></code>.
  320. </p>
  321. </div>
  322. </div>
  323. <div class="interface-member _3" id="members.InfixOp">
  324. <div class="interface-member-code">
  325. <a class="interface-member-backlink" href="#interface.InfixOp:B:"></a>
  326. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">InfixOp</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  327. </pre>
  328. </div>
  329. <div class="interface-member-description">
  330. <p class="para _1">
  331. <code class="fsharp"><span class="ci">InfixOp</span><span class="cp">(</span><span class="ci">opStr</span><span class="cp">,</span> <span
  332. class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span class="cp">,</span> <span
  333. class="ci">assoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code> represents an infix operator
  334. definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  335. class="ci">OperatorPrecedenceParser</span></a></code>.
  336. </p>
  337. </div>
  338. </div>
  339. <div class="interface-member _4" id="members.TernaryOp">
  340. <div class="interface-member-code">
  341. <a class="interface-member-backlink" href="#interface.TernaryOp:B:"></a>
  342. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">TernaryOp</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  343. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  344. </pre>
  345. </div>
  346. <div class="interface-member-description">
  347. <p class="para _1">
  348. <code class="fsharp"><span class="ci">TernaryOp</span><span class="cp">(</span><span class="ci">op1Str</span><span
  349. class="cp">,</span> <span class="ci">wsAfterOp1Parser</span><span class="cp">,</span> <span class="ci">op2Str</span><span
  350. class="cp">,</span> <span class="ci">wsAfterOp2Parser</span><span class="cp">,</span> <span class="ci">prec</span><span
  351. class="cp">,</span> <span class="ci">assoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  352. represents a ternary operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  353. class="ci">OperatorPrecedenceParser</span></a></code>.
  354. </p>
  355. </div>
  356. </div>
  357. <div class="interface-member _5" id="members.PrefixOp:39:">
  358. <div class="interface-member-code">
  359. <a class="interface-member-backlink" href="#interface.PrefixOp:39::B:"></a>
  360. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">PrefixOp'</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  361. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  362. </pre>
  363. </div>
  364. <div class="interface-member-description">
  365. <p class="para _1">
  366. <code class="fsharp"><span class="ci">PrefixOp'</span><span class="cp">(</span><span class="ci">opStr</span><span
  367. class="cp">,</span> <span class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span
  368. class="cp">,</span> <span class="ci">isAssoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  369. represents a prefix operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  370. class="ci">OperatorPrecedenceParser</span></a></code>. The state passed as an argument to the function is captured immediately before the
  371. operator string is parsed and contains the position of the operator.
  372. </p>
  373. </div>
  374. </div>
  375. <div class="interface-member _6" id="members.PostfixOp:39:">
  376. <div class="interface-member-code">
  377. <a class="interface-member-backlink" href="#interface.PostfixOp:39::B:"></a>
  378. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">PostfixOp'</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  379. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <span class="ci">bool</span> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  380. </pre>
  381. </div>
  382. <div class="interface-member-description">
  383. <p class="para _1">
  384. <code class="fsharp"><span class="ci">PostfixOp'</span><span class="cp">(</span><span class="ci">opStr</span><span
  385. class="cp">,</span> <span class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span
  386. class="cp">,</span> <span class="ci">isAssoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  387. represents a postfix operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  388. class="ci">OperatorPrecedenceParser</span></a></code>. The state passed as an argument to the function is captured immediately before the
  389. operator string is parsed and contains the position of the operator.
  390. </p>
  391. </div>
  392. </div>
  393. <div class="interface-member _7" id="members.InfixOp:39:">
  394. <div class="interface-member-code">
  395. <a class="interface-member-backlink" href="#interface.InfixOp:39::B:"></a>
  396. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">InfixOp'</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  397. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a> <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  398. </pre>
  399. </div>
  400. <div class="interface-member-description">
  401. <p class="para _1">
  402. <code class="fsharp"><span class="ci">InfixOp'</span><span class="cp">(</span><span class="ci">opStr</span><span
  403. class="cp">,</span> <span class="ci">wsAfterOpParser</span><span class="cp">,</span> <span class="ci">prec</span><span
  404. class="cp">,</span> <span class="ci">assoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  405. represents an infix operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  406. class="ci">OperatorPrecedenceParser</span></a></code>. The state passed as an argument to the function is captured immediately before the
  407. operator string is parsed and contains the position of the operator.
  408. </p>
  409. </div>
  410. </div>
  411. <div class="interface-member _8" id="members.TernaryOp:39:">
  412. <div class="interface-member-code">
  413. <a class="interface-member-backlink" href="#interface.TernaryOp:39::B:"></a>
  414. <pre class="code fsharp"><span class="cp">|</span> <span class="interface-member-marker"><span class="ci">TernaryOp'</span></span> <span class="ck">of</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cp">*</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ci">unit</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  415. <span class="cp">*</span> <span class="ci">int</span> <span class="cp">*</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a>
  416. <span class="cp">*</span> <span class="cp">(</span><a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span> <span class="cr">-&gt;</span> <span class="ctv">'a</span><span class="cp">)</span>
  417. </pre>
  418. </div>
  419. <div class="interface-member-description">
  420. <p class="para _1">
  421. <code class="fsharp"><span class="ci">TernaryOp'</span><span class="cp">(</span><span class="ci">op1Str</span><span
  422. class="cp">,</span> <span class="ci">wsAfterOp1Parser</span><span class="cp">,</span> <span class="ci">op2Str</span><span
  423. class="cp">,</span> <span class="ci">wsAfterOp2Parser</span><span class="cp">,</span> <span class="ci">prec</span><span
  424. class="cp">,</span> <span class="ci">assoc</span><span class="cp">,</span> <span class="ci">f</span><span class="cp">)</span></code>
  425. represents a ternary operator definition for an <code class="fsharp"><a href="#members.OperatorPrecedenceParser"><span
  426. class="ci">OperatorPrecedenceParser</span></a></code>. The states passed as arguments to the function are captured immediately before the
  427. first and second operator strings are parsed and contain the positions of the operators.
  428. </p>
  429. </div>
  430. </div>
  431. </div>
  432. </div>
  433. </div>
  434. </div>
  435. <div class="interface-member _3" id="members.OperatorPrecedenceParser">
  436. <div class="interface-member-code">
  437. <a class="interface-member-backlink" href="#interface.OperatorPrecedenceParser:B:"></a>
  438. <pre class="code fsharp"><span class="ck">type</span> <span class="interface-member-marker"><span class="ci">OperatorPrecedenceParser</span></span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span></pre>
  439. </div>
  440. <div class="interface-member-description">
  441. <p class="para _1">
  442. The <code class="fsharp"><span class="ci">OperatorPrecedenceParser</span></code> class (OPP) represents a dynamically configurable parser for
  443. parsing expression grammars involving binary infix (e.g. <code class="fsharp"><span class="cn">1</span> <span class="co">+</span> <span
  444. class="cn">1</span></code>), unary prefix (e.g. <code class="fsharp"><span class="co">-</span><span class="cn">1</span></code>), unary
  445. postfix (e.g. <code class="fsharp"><span class="cn">1</span><span class="co">++</span></code>) and Cstyle ternary operators (e.g. <code
  446. class="fsharp"><span class="ci">x</span> <span class="co">&gt;</span> <span class="cn">0</span> <span class="cp">?</span> <span
  447. class="cn">1</span> <span class="cp">:</span> <span class="cn">2</span></code>).
  448. </p>
  449. <div class="para _2">
  450. <pre class="code fsharp"><span class="ck">type</span> <span class="ci">OperatorPrecedenceParser</span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cp">=</span>
  451. <span class="ck">new</span><span class="cp">:</span> <span class="cp">?</span><span class="ci">ops</span><span class="cp">:</span><span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">OperatorPrecedenceParser</span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  452. <span class="ck">member</span> <a href="#members.ExpressionParser"><span class="ci">ExpressionParser</span></a><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  453. <span class="ck">member</span> <a href="#members.TermParser"><span class="ci">TermParser</span></a><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  454. <span class="ck">member</span> <a href="#members.AddOperator"><span class="ci">AddOperator</span></a><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  455. <span class="ck">member</span> <a href="#members.AddOperators"><span class="ci">AddOperators</span></a><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  456. <span class="ck">member</span> <a href="#members.RemoveOperator"><span class="ci">RemoveOperator</span></a><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  457. <span class="ck">member</span> <a href="#members.RemoveInfixOp"><span class="ci">RemoveInfixOp</span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  458. <span class="ck">member</span> <a href="#members.RemovePrefixOp"><span class="ci">RemovePrefixOp</span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  459. <span class="ck">member</span> <a href="#members.RemovePostfixOp"><span class="ci">RemovePostfixOp</span></a><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  460. <span class="ck">member</span> <a href="#members.RemoveTernaryOp"><span class="ci">RemoveTernaryOp</span></a><span class="cp">:</span> <span class="ci">string</span><span class="cp">*</span><span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  461. <span class="ck">member</span> <a href="#members.Operators"><span class="ci">Operators</span></a><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span>
  462. <span class="ck">member</span> <a href="#members.OperatorConflictHandler"><span class="ci">OperatorConflictHandler</span></a><span class="cp">:</span> <span class="cp">(</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  463. <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  464. <span class="cr">-&gt;</span> <span class="ci">string</span><span class="cp">)</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  465. </pre>
  466. </div>
  467. <p class="para _3">
  468. You can configure an OPP instance by adding and removing operator definitions in the form of <code class="fsharp"><a
  469. href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a></code> values. If you add an operator that conflicts with a
  470. previous operator definition, <code class="fsharp"><a href="#members.AddOperator"><span class="ci">AddOperator</span></a></code> will raise
  471. an <code class="fsharp"><a href="http://msdn.microsoft.com/en-us/library/system.argumentexception.aspx"><span
  472. class="ci">ArgumentException</span></a></code>. The <code class="fsharp"><a href="#members.Operators"><span
  473. class="ci">Operators</span></a></code> property returns a snapshot of the currently defined set of operators. The <code class="fsharp"><a
  474. href="#members.RemoveInfixOp"><span class="ci">RemoveInfixOp</span></a></code>, <code class="fsharp"><a href="#members.RemovePrefixOp"><span
  475. class="ci">RemovePrefixOp</span></a></code>, etc. members remove operator definitions based only on their text representation. All <code
  476. class="fsharp"><span class="ci">Remove</span><span class="co">...</span></code> members return <code class="fsharp"><span
  477. class="cb">false</span></code> if no matching operator was previously defined, otherwise <code class="fsharp"><span
  478. class="cb">true</span></code>.
  479. </p>
  480. <p class="para _4">
  481. The actual expression parser of the OPP is exposed through the <code class="fsharp"><strong><a href="#members.ExpressionParser"><span
  482. class="ci">ExpressionParser</span></a></strong></code> property. The <code class="fsharp"><a href="#members.ExpressionParser"><span
  483. class="ci">ExpressionParser</span></a></code> value is a constant closure that forwards all work to an internal instance method. This ensures
  484. that the behaviour of the expression parser always reflects the latest configuration of the OPP instance. You can safely call the <code
  485. class="fsharp"><a href="#members.ExpressionParser"><span class="ci">ExpressionParser</span></a></code> concurrently from multiple threads, as
  486. long as the configuration of the OPP instance is not changed at the same time.
  487. </p>
  488. <p class="para _5">
  489. Before you can call the <code class="fsharp"><a href="#members.ExpressionParser"><span class="ci">ExpressionParser</span></a></code> you
  490. first need to set the <code class="fsharp"><strong><a href="#members.TermParser"><span class="ci">TermParser</span></a></strong></code>. The
  491. OPP instance uses the <code class="fsharp"><a href="#members.TermParser"><span class="ci">TermParser</span></a></code> to parse the terms in
  492. between the operators. Often the <code class="fsharp"><a href="#members.TermParser"><span class="ci">TermParser</span></a></code> will not
  493. just parse terminal values but will also recursively call the <code class="fsharp"><a href="#members.ExpressionParser"><span
  494. class="ci">ExpressionParser</span></a></code>, for example to parse an expression between parentheses. Note that the <code class="fsharp"><a
  495. href="#members.TermParser"><span class="ci">TermParser</span></a></code> also needs to consume any trailing whitespace.
  496. </p>
  497. <div class="para _6">
  498. <p>This example shows how to define a parser for very simple arithmetic expressions:</p>
  499. <pre class="code fsharp"><span class="ck">open</span> <a href="primitives.html"><span class="ci">FParsec</span><span class="cm">.</span><span class="ci">Primitives</span></a>
  500. <span class="ck">open</span> <span class="ci">FParsec</span><span class="cm">.</span><span class="ci">CharParser</span>
  501. <span class="ck">let</span> <span class="ci">ws</span> <span class="cp">=</span> <a href="charparsers.html#members.spaces"><span class="ci">spaces</span></a>
  502. <span class="ck">let</span> <span class="ci">ch</span> <span class="ci">c</span> <span class="cp">=</span> <a href="charparsers.html#members.skipChar"><span class="ci">skipChar</span></a> <span class="ci">c</span> <a href="primitives.html#members.:62::62::.:"><span class="co">&gt;&gt;.</span></a> <span class="ci">ws</span>
  503. <span class="ck">let</span> <span class="ci">opp</span> <span class="cp">=</span> <span class="ck">new</span> <span class="ci">OperatorPrecedenceParser</span><span class="cp">&lt;</span><span class="ci">_</span><span class="cp">,</span><span class="ci">_</span><span class="cp">&gt;</span><span class="cp">()</span>
  504. <span class="ck">let</span> <span class="ci">expr</span> <span class="cp">=</span> <span class="ci">opp</span><span class="cm">.</span><a href="#members.ExpressionParser"><span class="ci">ExpressionParser</span></a>
  505. <span class="ck">let</span> <span class="ci">term</span> <span class="cp">=</span> <span class="cp">(</span><a href="charparsers.html#members.pfloat"><span class="ci">pfloat</span></a> <a href="primitives.html#members.:.::62::62:"><span class="co">.&gt;&gt;</span></a> <span class="ci">ws</span><span class="cp">)</span> <a href="primitives.html#members.:60::124::62:"><span class="co">&lt;|&gt;</span></a> <a href="primitives.html#members.between"><span class="ci">between</span></a> <span class="cp">(</span><span class="ci">ch</span> <span class="cc"><span class="left-delimiter">'</span>(<span class="right-delimiter">'</span></span><span class="cp">)</span> <span class="cp">(</span><span class="ci">ch</span> <span class="cc"><span class="left-delimiter">'</span>)<span class="right-delimiter">'</span></span><span class="cp">)</span> <span class="ci">expr</span>
  506. <span class="ci">opp</span><span class="cm">.</span><a href="#members.TermParser"><span class="ci">TermParser</span></a> <span class="co">&lt;-</span> <span class="ci">term</span>
  507. <span class="ci">opp</span><span class="cm">.</span><a href="#members.AddOperator"><span class="ci">AddOperator</span></a><span class="cp">(</span><a href="#members.InfixOp"><span class="ci">InfixOp</span></a><span class="cp">(</span><span class="cs"><span class="left-delimiter">"</span>+<span class="right-delimiter">"</span></span><span class="cp">,</span> <span class="ci">ws</span><span class="cp">,</span> <span class="cn">1</span><span class="cp">,</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a><span class="cm">.</span><span class="ci">Left</span><span class="cp">,</span> <span class="ck">fun</span> <span class="ci">x</span> <span class="ci">y</span> <span class="cr">-&gt;</span> <span class="ci">x</span> <span class="co">+</span> <span class="ci">y</span><span class="cp">)</span><span class="cp">)</span>
  508. <span class="ci">opp</span><span class="cm">.</span><a href="#members.AddOperator"><span class="ci">AddOperator</span></a><span class="cp">(</span><a href="#members.InfixOp"><span class="ci">InfixOp</span></a><span class="cp">(</span><span class="cs"><span class="left-delimiter">"</span>*<span class="right-delimiter">"</span></span><span class="cp">,</span> <span class="ci">ws</span><span class="cp">,</span> <span class="cn">2</span><span class="cp">,</span> <a href="#members.Assoc"><span class="ci">Assoc</span></a><span class="cm">.</span><span class="ci">Left</span><span class="cp">,</span> <span class="ck">fun</span> <span class="ci">x</span> <span class="ci">y</span> <span class="cr">-&gt;</span> <span class="ci">x</span> <span class="co">*</span> <span class="ci">y</span><span class="cp">)</span><span class="cp">)</span>
  509. </pre>
  510. <pre class="code fsharp"><span class="cp">&gt;</span> <a href="charparsers.html#members.run"><span class="ci">run</span></a> <span class="ci">expr</span> <span class="cs"><span class="left-delimiter">"</span>1 + 2*(3 + 4)<span class="right-delimiter">"</span></span><span class="cp">;</span>
  511. <span class="ck">val</span> <span class="ci">it</span> <span class="cp">:</span> <a href="charparsers.html#members.ParserResult"><span class="ci">ParserResult</span></a><span class="cp">&lt;</span><span class="ci">float</span><span class="cp">,</span><span class="ci">unit</span><span class="cp">&gt;</span> <span class="cp">=</span> <a href="charparsers.html#members.Success"><span class="ci">Success</span></a><span class="cp">:</span> <span class="cn">15.0</span>
  512. </pre>
  513. </div>
  514. <p class="para _7">
  515. <a id="members.precedence-associativity"></a>The following points explain <em>how expressions are parsed depending on precedence and
  516. associativity</em> of the involved operators:
  517. </p>
  518. <div class="para _8">
  519. <ul class="l1">
  520. <li class="_1">
  521. Operators with higher precedence bind tighter. For example, if the prefix operator &#x201C;~&#x201D; has a lower precedence than the infix
  522. operator &#x201C;&amp;&#x201D; then &#x201C;~x&amp;y&#x201D; will be parsed as &#x201C;~(x&amp;y)&#x201D;.
  523. </li>
  524. </ul>
  525. </div>
  526. <div class="para _9">
  527. <ul class="l1">
  528. <li class="_1">
  529. Ternary operators are treated as special infix operators. The middle expression (e.g. &#x201C;expr2&#x201D; in &#x201C;expr1 ? expr2 :
  530. expr3&#x201D;) is parsed as a &#x201C;fresh&#x201D; expression that is not influenced by the precedence of the surrounding operators.
  531. </li>
  532. </ul>
  533. </div>
  534. <div class="para _0">
  535. <ul class="l1">
  536. <li class="_1">
  537. <p>Operators with identical precedence are parsed as follows:</p>
  538. <pre class="code other">Here o1, o2 are two infix operators,
  539. pre1, pre2 are two prefix operators,
  540. po1, po2 are two postfix operators
  541. and all operators have identical precedence.
  542. x o1 pre1 y ==&gt; x o1 (pre1 y)
  543. x o1 y po1 ==&gt; x o1 (y po1)
  544. x o1 y o2 z ==&gt; (x o1 y) o2 z if o1 and o2 are left-associative
  545. x o1 y o2 z ==&gt; x o1 (y o2 z) if o1 and o2 are right-associative
  546. pre1 x po1 ==&gt; (pre1 x) po1 if pre1 or po1 is associative
  547. pre1 pre2 x ==&gt; pre1 (pre2 x) if pre1 or pre2 is associative
  548. x po1 po2 ==&gt; (x po1) po2 if po1 or po2 is associative
  549. </pre>
  550. </li>
  551. </ul>
  552. </div>
  553. <div class="para _1">
  554. <ul class="multi-para l1">
  555. <li class="_1">
  556. <p class="para _1">
  557. If the parser encounters conflicting operators, e.g. if a rightassociative infix operators follows a leftassociative operator of the
  558. same precedence level, the <code class="fsharp"><a href="#members.OperatorConflictHandler"><span
  559. class="ci">OperatorConflictHandler</span></a></code> is called. The arguments passed to the handler are the conflicting operators together
  560. with the parser states as captured immediately before the operators were parsed. If the conflict handler returns null or an empty string,
  561. the operators are parsed as if both were (left)associative, otherwise a parser error with the returned string is generated. The default
  562. handler always generates an error.
  563. </p>
  564. <div class="para _2">
  565. <p>
  566. In the following situations the <code class="fsharp"><a href="#members.OperatorConflictHandler"><span
  567. class="ci">OperatorConflictHandler</span></a></code> will be called and the expression will only be parsed as indicated if the handler
  568. returns an empty error message:
  569. </p>
  570. <pre class="code other">[Same notation as above, all operators have identical precedence.]
  571. x o1 y o2 z ==&gt; (x o1 y) o2 z if o1 and o2 have different associativity
  572. or o1 and o2 are non-associative
  573. pre1 pre2 x ==&gt; pre1 (pre2 y) if pre1 and pre2 are non-associative
  574. pre1 x po1 ==&gt; (pre1 y) po1 if pre1 and po1 are non-associative
  575. x po1 po2 ==&gt; (y po1) po2 if po1 and po2 are non-associative
  576. </pre>
  577. </div>
  578. </li>
  579. </ul>
  580. </div>
  581. <div class="para _2">
  582. <div class="interface-members">
  583. <div class="interface-member _1" id="members.new">
  584. <div class="interface-member-code">
  585. <a class="interface-member-backlink" href="#interface.new:B:"></a>
  586. <pre class="code fsharp"><span class="interface-member-marker"><span class="ck">new</span></span><span class="cp">:</span> <span class="cp">?</span><span class="ci">ops</span><span class="cp">:</span><span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">OperatorPrecedenceParser</span><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  587. </pre>
  588. </div>
  589. <div class="interface-member-description">
  590. <p class="para _1">
  591. Constructs an <code class="fsharp"><span class="ci">OperatorPrecedenceParser</span></code> instance and optionally adds the given
  592. operators.
  593. </p>
  594. </div>
  595. </div>
  596. <div class="interface-member _2" id="members.ExpressionParser">
  597. <div class="interface-member-code">
  598. <a class="interface-member-backlink" href="#interface.ExpressionParser:B:"></a>
  599. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">ExpressionParser</span></span><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  600. </pre>
  601. </div>
  602. <div class="interface-member-description">
  603. <p class="para _1">
  604. The expression parser. This is a constant closure that forwards all work to an internal instance method, so that the expression parser
  605. always reflects the latest configuration of the <code class="fsharp"><span class="ci">OperatorPrecedenceParser</span></code> instance.
  606. The parser can be safely called from different threads as long as the <code class="fsharp"><span
  607. class="ci">OperatorPrecedenceParser</span></code> instance is not mutated at the same time.
  608. </p>
  609. </div>
  610. </div>
  611. <div class="interface-member _3" id="members.TermParser">
  612. <div class="interface-member-code">
  613. <a class="interface-member-backlink" href="#interface.TermParser:B:"></a>
  614. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">TermParser</span></span><span class="cp">:</span> <a href="primitives.html#members.Parser"><span class="ci">Parser</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span> <span class="ctv">'u</span><span class="cp">&gt;</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  615. </pre>
  616. </div>
  617. <div class="interface-member-description">
  618. <p class="para _1">
  619. This parser is called to parse the terms in between the operators. There is no default, so you must set this parser before you can call
  620. the <code class="fsharp"><a href="#members.ExpressionParser"><span class="ci">ExpressionParser</span></a></code>. Note that the term
  621. parser is also expected to parse any whitespace after a term.
  622. </p>
  623. </div>
  624. </div>
  625. <div class="interface-member _4" id="members.OperatorConflictHandler">
  626. <div class="interface-member-code">
  627. <a class="interface-member-backlink" href="#interface.OperatorConflictHandler:B:"></a>
  628. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">OperatorConflictHandler</span></span><span class="cp">:</span> <span class="cp">(</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  629. <span class="cr">-&gt;</span> <a href="state.html"><span class="ci">State</span></a><span class="cp">&lt;</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span>
  630. <span class="cr">-&gt;</span> <span class="ci">string</span><span class="cp">)</span> <span class="ck">with</span> <span class="ci">get</span><span class="cp">,</span> <span class="ci">set</span>
  631. </pre>
  632. </div>
  633. <div class="interface-member-description">
  634. <p class="para _1">This function is called when the precedence parser encounters two conflicting operators in the parser input.</p>
  635. <p class="para _2">
  636. If the conflict handler returns <code class="fsharp"><span class="cnu">null</span></code> or an empty string, the operators are parsed as
  637. if both were (left)associative, otherwise a parser error with the returned message is generated. The default handler will always
  638. generate an error message.
  639. </p>
  640. </div>
  641. </div>
  642. <div class="interface-member _5" id="members.AddOperator">
  643. <div class="interface-member-code">
  644. <a class="interface-member-backlink" href="#interface.AddOperator:B:"></a>
  645. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">AddOperator</span></span><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  646. </pre>
  647. </div>
  648. <div class="interface-member-description">
  649. <p class="para _1">
  650. Adds an operator to the grammar. Raises an <code class="fsharp"><a
  651. href="http://msdn.microsoft.com/en-us/library/system.argumentexception.aspx"><span class="ci">ArgumentException</span></a></code> if the
  652. operator definition conflicts with a previous definition or contains empty strings or a nonpositive precedence.
  653. </p>
  654. </div>
  655. </div>
  656. <div class="interface-member _6" id="members.AddOperators">
  657. <div class="interface-member-code">
  658. <a class="interface-member-backlink" href="#interface.AddOperators:B:"></a>
  659. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">AddOperators</span></span><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">unit</span>
  660. </pre>
  661. </div>
  662. <div class="interface-member-description">
  663. <p class="para _1">
  664. Calls <code class="fsharp"><a href="#members.AddOperator"><span class="ci">AddOperator</span></a></code> with each operator in the given
  665. sequence.
  666. </p>
  667. </div>
  668. </div>
  669. <div class="interface-member _7" id="members.RemoveOperator">
  670. <div class="interface-member-code">
  671. <a class="interface-member-backlink" href="#interface.RemoveOperator:B:"></a>
  672. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">RemoveOperator</span></span><span class="cp">:</span> <a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  673. </pre>
  674. </div>
  675. <div class="interface-member-description">
  676. <p class="para _1">
  677. Removes the given operator from the grammar. Returns <code class="fsharp"><span class="cb">false</span></code> if the operator was not
  678. previously registered, otherwise <code class="fsharp"><span class="cb">true</span></code>.
  679. </p>
  680. </div>
  681. </div>
  682. <div class="interface-member _8" id="members.RemoveInfixOp">
  683. <div class="interface-member-code">
  684. <a class="interface-member-backlink" href="#interface.RemoveInfixOp:B:"></a>
  685. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">RemoveInfixOp</span></span><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  686. </pre>
  687. </div>
  688. <div class="interface-member-description">
  689. <p class="para _1">
  690. Removes the infix operator with the given string from the grammar. Returns <code class="fsharp"><span class="cb">false</span></code> if
  691. no infix operator with that string was previously registered, otherwise <code class="fsharp"><span class="cb">true</span></code>.
  692. </p>
  693. </div>
  694. </div>
  695. <div class="interface-member _9" id="members.RemovePrefixOp">
  696. <div class="interface-member-code">
  697. <a class="interface-member-backlink" href="#interface.RemovePrefixOp:B:"></a>
  698. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">RemovePrefixOp</span></span><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  699. </pre>
  700. </div>
  701. <div class="interface-member-description">
  702. <p class="para _1">
  703. Removes the prefix operator with the given string from the grammar. Returns <code class="fsharp"><span class="cb">false</span></code> if
  704. no prefix operator with that string was previously registered, otherwise <code class="fsharp"><span class="cb">true</span></code>.
  705. </p>
  706. </div>
  707. </div>
  708. <div class="interface-member _0" id="members.RemovePostfixOp">
  709. <div class="interface-member-code">
  710. <a class="interface-member-backlink" href="#interface.RemovePostfixOp:B:"></a>
  711. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">RemovePostfixOp</span></span><span class="cp">:</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  712. </pre>
  713. </div>
  714. <div class="interface-member-description">
  715. <p class="para _1">
  716. Removes the postfix operator with the given string from the grammar. Returns <code class="fsharp"><span class="cb">false</span></code> if
  717. no postfix operator with that string was previously registered, otherwise <code class="fsharp"><span class="cb">true</span></code>.
  718. </p>
  719. </div>
  720. </div>
  721. <div class="interface-member _1" id="members.RemoveTernaryOp">
  722. <div class="interface-member-code">
  723. <a class="interface-member-backlink" href="#interface.RemoveTernaryOp:B:"></a>
  724. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">RemoveTernaryOp</span></span><span class="cp">:</span> <span class="ci">string</span> <span class="cp">*</span> <span class="ci">string</span> <span class="cr">-&gt;</span> <span class="ci">bool</span>
  725. </pre>
  726. </div>
  727. <div class="interface-member-description">
  728. <p class="para _1">
  729. Removes the ternary operator with the given strings from the grammar. Returns <code class="fsharp"><span class="cb">false</span></code>
  730. if no ternary operator with these strings was previously registered, otherwise <code class="fsharp"><span class="cb">true</span></code>.
  731. </p>
  732. </div>
  733. </div>
  734. <div class="interface-member _2" id="members.Operators">
  735. <div class="interface-member-code">
  736. <a class="interface-member-backlink" href="#interface.Operators:B:"></a>
  737. <pre class="code fsharp"><span class="ck">member</span> <span class="interface-member-marker"><span class="ci">Operators</span></span><span class="cp">:</span> <span class="ci">seq</span><span class="cp">&lt;</span><a href="#members.PrecedenceParserOp"><span class="ci">PrecedenceParserOp</span></a><span class="cp">&lt;</span><span class="ctv">'a</span><span class="cp">,</span><span class="ctv">'u</span><span class="cp">&gt;</span><span class="cp">&gt;</span>
  738. </pre>
  739. </div>
  740. <div class="interface-member-description">
  741. <p class="para _1">
  742. Returns a sequence with a snapshot of the operators currently registered with the <code class="fsharp"><span
  743. class="ci">OperatorPrecedenceParser</span></code>.
  744. </p>
  745. </div>
  746. </div>
  747. </div>
  748. </div>
  749. </div>
  750. </div>
  751. </div>
  752. </div>
  753. </div>
  754. </div>
  755. </div>
  756. </div>
  757. </div>
  758. </div>
  759. </body>
  760. </html>