Source

fparsec / Doc / html / about / fparsec-vs-alternatives.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>FParsec vs alternatives</title>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style.css" />
 <link rel="stylesheet" type="text/css" media="screen" href="../css/screen-sidebar.css" />
 <!--[if lt IE 9]>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie.css" />
 <![endif]-->
 <!--[if IE 6]>
 <link rel="stylesheet" type="text/css" media="all" href="../css/style-ie6.css" />
 <![endif]-->
 <link rel="stylesheet" type="text/css" media="print" href="../css/print.css" />
</head>
<body>
 <div id="fixed-layer">
 <div id="fixed-wrapper">
 <div id="sidebar">
  <div id="top-links"><span><a href="http://bitbucket.org/fparsec/main">FParsec @ BitBucket</a> | <a href="https://bitbucket.org/fparsec/main/issues">Report a bug</a> | <a href="mailto:fparsec [at] quanttec.com?subject=FParsec&amp;body=Hello Stephan,%0A%0A[your feedback]">Feedback</a></span></div>
  <div id="nav-tree">
   <table class="nav n1">
    <tbody class="nav-open n1">
     <tr class="nav-entry n1 _1">
      <td class="nav-number n1"></td>
      <td class="nav-title n1"><a href="../index.html">FParsec Documentation</a></td>
     </tr>
     <tr class="nav-subentries n1 _1">
      <td class="nav-subentries-number n1"></td>
      <td class="nav-subentries n1">
       <table class="nav n2">
        <tbody class="nav-open n2">
         <tr class="nav-entry n2 _1">
          <td class="nav-number n2"><a href="index.html"><span class="section-number">1</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="index.html">About FParsec</a></td>
         </tr>
         <tr class="nav-subentries n2 _1">
          <td class="nav-subentries-number n2"></td>
          <td class="nav-subentries n2">
           <table class="nav n3">
            <tbody class="nav-open selected n3">
             <tr class="nav-entry selected n3 _1">
              <td class="nav-number selected n3"><a href="#"><span class="section-number">1</span><span class="nav-space"></span></a></td>
              <td class="nav-title selected n3"><a href="#">FParsec vs alternatives</a></td>
             </tr>
            </tbody>
            <tbody class="nav-after-open n3">
             <tr class="nav-entry n3 _2">
              <td class="nav-number n3">
               <a href="status-and-roadmap.html"><span class="section-number">2</span><span class="nav-space"></span></a>
              </td>
              <td class="nav-title n3"><a href="status-and-roadmap.html">Status and roadmap</a></td>
             </tr>
             <tr class="nav-entry n3 _3">
              <td class="nav-number n3"><a href="changelog.html"><span class="section-number">3</span><span class="nav-space"></span></a></td>
              <td class="nav-title n3"><a href="changelog.html">Changelog</a></td>
             </tr>
             <tr class="nav-entry n3 _4">
              <td class="nav-number n3"><a href="contact.html"><span class="section-number">4</span><span class="nav-space"></span></a></td>
              <td class="nav-title n3"><a href="contact.html">Contact</a></td>
             </tr>
            </tbody>
           </table>
          </td>
         </tr>
        </tbody>
        <tbody class="nav-after-open n2">
         <tr class="nav-entry n2 _2">
          <td class="nav-number n2"><a href="../license.html"><span class="section-number">2</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../license.html">License</a></td>
         </tr>
         <tr class="nav-entry n2 _3">
          <td class="nav-number n2">
           <a href="../download-and-installation.html"><span class="section-number">3</span><span class="nav-space"></span></a>
          </td>
          <td class="nav-title n2"><a href="../download-and-installation.html">Download and installation</a></td>
         </tr>
         <tr class="nav-entry n2 _4">
          <td class="nav-number n2"><a href="../tutorial.html"><span class="section-number">4</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../tutorial.html">Tutorial</a></td>
         </tr>
         <tr class="nav-entry n2 _5">
          <td class="nav-number n2"><a href="../users-guide/index.html"><span class="section-number">5</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../users-guide/index.html">User’s Guide</a></td>
         </tr>
         <tr class="nav-entry n2 _6">
          <td class="nav-number n2"><a href="../reference/index.html"><span class="section-number">6</span><span class="nav-space"></span></a></td>
          <td class="nav-title n2"><a href="../reference/index.html">Reference</a></td>
         </tr>
        </tbody>
       </table>
      </td>
     </tr>
    </tbody>
   </table>
  </div>
  <div id="copyright">
    <span>Copyright © 2012 <a href="../about/contact.html">Stephan Tolksdorf</a></span>
  </div>
 </div>
 </div>
 </div>
 <div id="wrapper">
 <div id="main">
 <div id="main-content">
 <div id="breadcrumbs">
  <span class="breadcrumbs">
   <span id="breadcrumbs-parents"><a href="../index.html">FParsec Documentation</a><span class="breadcrumbs-sep"> > </span><a href="index.html">About FParsec</a></span><span class="breadcrumbs-sep"> > </span>FParsec vs alternatives
  </span>
 </div>
 <div class="section s2">
  <h1 class="title h2"><span><span class="section-number">1.1</span> FParsec vs alternatives</span></h1>
  <div class="intro i2">
   <div class="para _1">
    <p>
     The following tables contain a bullet‐point comparison between FParsec and the two main alternatives for parsing with F#: parser generator tools
     (e.g. fslex &amp; fsyacc) and &#x201C;hand‐written&#x201D; recursive descent parsers.
    </p>
   </div>
   <div class="para _2 lcinp">
    <div id="relative-advantages" class="table">
     <table cellspacing="0">
      <caption>
       <span class="table-caption-prefix">Table <span class="table-number">1.1.1</span>: </span><span class="table-title">Relative advantages</span>
      </caption>
      <thead>
       <tr class="_1">
        <th class="_1">Parser‐generator tools</th>
        <th class="_2">FParsec</th>
        <th class="_3">Hand‐written<br /> recursive‐descent parser</th>
       </tr>
      </thead>
      <tbody>
       <tr class="_1">
        <td class="_1">
         <ul class="l1">
          <li class="_1">Declarative and easy‐to‐read syntax</li>
          <li class="_2">Ensures adherence to grammar formalism</li>
          <li class="_3">Can check for certain kinds of ambiguity in grammar</li>
          <li class="_4">
           You don’t have to think about performance. Either the generated parser is fast enough, or not. There’s not much you can do about it.
          </li>
         </ul>
        </td>
        <td class="_2">
         <ul class="l1">
          <li class="_1">Implemented as F# library, so no extra tools or build steps</li>
          <li class="_2">Parsers are first‐class values within the language</li>
          <li class="_3">Succinct and expressive syntax</li>
          <li class="_4">Modular and easily extensible</li>
          <li class="_5">Extensive set of predefined parsers and combinators</li>
          <li class="_6">Semi‐automatically generated, highly readable error messages</li>
          <li class="_7">Supports arbitrary lookahead and backtracking</li>
          <li class="_8">Runtime‐configurable operator‐precedence parser component</li>
          <li class="_9">Does not require a pre‐parsing tokenization phase</li>
          <li class="_0">Comprehensive documentation</li>
          <li class="_1">Extensively unit‐tested</li>
         </ul>
        </td>
        <td class="_3">
         <ul class="l1">
          <li class="_1">No extra tools or build steps</li>
          <li class="_2">Most amenable to individual requirements</li>
          <li class="_3">Potentially as fast as technically possible</li>
          <li class="_4">Parsers are relatively portable if you stick to simple language features and keep library dependencies to a minimum</li>
         </ul>
        </td>
       </tr>
      </tbody>
     </table>
    </div>
   </div>
   <div class="para _3 lcinp">
    <div id="relative-disadvantages" class="table">
     <table cellspacing="0">
      <caption>
       <span class="table-caption-prefix">Table <span class="table-number">1.1.2</span>: </span><span class="table-title">Relative
       disadvantages</span>
      </caption>
      <thead>
       <tr class="_1">
        <th class="_1">Parser‐generator tools</th>
        <th class="_2">FParsec</th>
        <th class="_3">Hand‐written<br /> recursive‐descent parser</th>
       </tr>
      </thead>
      <tbody>
       <tr class="_1">
        <td class="_1">
         <ul class="l1">
          <li class="_1">Restricted to features of grammar formalism</li>
          <li class="_2">Extra tools and compilation steps</li>
          <li class="_3">Reliance on opaque generator tool, that is often hard to debug, optimize or extend</li>
          <li class="_4">Static grammar that can’t be changed at runtime</li>
          <li class="_5">Often hard to generate good error messages</li>
          <li class="_6">Many tools generate comparatively slow parsers</li>
          <li class="_7">Some tools have only limited Unicode support</li>
          <li class="_8">Portability problems</li>
         </ul>
        </td>
        <td class="_2">
         <ul class="l1">
          <li class="_1">Tradeoff between declarativeness and performance</li>
          <li class="_2">Syntax less readable than PEG or Regular Expression syntax</li>
          <li class="_3"><a href="http://en.wikipedia.org/wiki/Left_recursion">Left‐recursive</a> grammar rules have to be rewritten</li>
          <li class="_4">Does not support a pre‐parsing tokenization phase</li>
          <li class="_5">You have to learn the API</li>
          <li class="_6">Limited to F#</li>
          <li class="_7">Code‐dependence on FParsec</li>
          <li class="_8">Aggressive performance optimizations add complexity to parts of the lower‐level FParsec source code</li>
         </ul>
        </td>
        <td class="_3">
         <ul class="l1">
          <li class="_1">You have to write everything yourself, which can take a lot of effort</li>
          <li class="_2">Implementing (fast) parsers requires some experience</li>
          <li class="_3">
           Expression (sub)grammars with infix operators can be ugly and inefficient to parse with a pure recursive‐descent parser, so you might also
           have to write some kind of embedded operator precedence parser
          </li>
         </ul>
        </td>
       </tr>
      </tbody>
     </table>
    </div>
   </div>
  </div>
 </div>
 </div>
 </div>
 </div>
</body>
</html>