<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="108089" data-post-id="108089">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyLib do
  def get_line(meta) do
    Keyword.get(meta, :line)
  end

  def annotate_parser_ast(ast, line, rule) do
    # This is stupid because we assume the input is a list of pairs,
    # while the output is a list of 3-tuples.
    # In the real version, the input will also be a list of 3-tuples.
    for {key, val} &lt;- ast do
      {key, %{line: line, rule: rule}, val}
    end
  end

  # If this is a simple assignment, annotate the parser AST with location information
  defp annotate_quoted_combinator({:=, _meta, [{rule_name, meta, nil} = lhs, rhs]}) do
    line = get_line(meta)

    quote do
      unquote(lhs) = MyLib.annotate_parser_ast(unquote(rhs), unquote(line), unquote(rule_name))
    end
  end

  # Else do nothing
  defp annotate_quoted_combinator(something_else) do
    something_else
  end

  defmacro combinators(do: {:__block__, _meta, exprs}) do
    annotated_exprs = Enum.map(exprs, &amp;annotate_quoted_combinator/1)

    quote do
      (unquote_splicing(annotated_exprs))
    end
  end
end

defmodule MyParser do
  import MyLib
  import NimbleParsec

  combinators do
    comb1 = string("abc")

    comb2 = string("xyz")

    comb3 =
      choice([
        comb1,
        comb2
      ])
  end

  IO.inspect(comb1, label: "comb1")
  IO.inspect(comb2, label: "comb2")
  IO.inspect(comb3, label: "comb3")
end
</code></pre>
<p>When you compile this code, you’ll get the following output:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Compiling 1 file (.ex)
comb1: [{:string, %{line: 43, rule: :comb1}, "abc"}]
comb2: [{:string, %{line: 45, rule: :comb2}, "xyz"}]
comb3: [
  {:choice, %{line: 47, rule: :comb3},
   [
     [{:string, %{line: 43, rule: :comb1}, "abc"}],
     [{:string, %{line: 45, rule: :comb2}, "xyz"}]
   ]}
]
</code></pre>
<p>Basically this adds a metadata field to the combinators. That way, if there is a problem, the compiler used by <code>defparsec</code> can give a nice error message containing the line number and the name of the “rule” (I’m stealing the name from ExSpirit). For this to work, the metadata field must be added to the combinators (I haven’t read enough of the nimble_parsec implementation to see if it this would be feasible, but it looks like it should be.</p>
<p>The idea is that the <code>combinators</code> macro just fills the metada in the parser AST. It does so by cleverly mixing functions and macros to control which parts of the (elixir) AST are evaluated and each ones are retuned as is.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108089" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/123">Post #122</a>
	                </div>
	            </div>
              <div id="likers-container-108089" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108089"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #122"></div>
  </section>
</div>
    <div class="postbit" id="108135" data-post-id="108135">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-livebook_core_team" data-username="josevalim" data-post="111" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/48/1787_2.png" class="avatar"> josevalim:</div>
<blockquote>
<p>This is compile time, so non anonymous functions for us.</p>
</blockquote>
</aside>
<p>Well, you could accept mfa tuples, or single atoms and treat the rest as a quoted expression. That way one could write <code>from_context(key, quote(do: fn x -&gt; ... end))</code></p>
<p>It would be very convenient and I don’t mind wrapping it in a quote.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108135" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/124">Post #123</a>
	                </div>
	            </div>
              <div id="likers-container-108135" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108135"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #123"></div>
  </section>
</div>
    <div class="postbit" id="108372" data-post-id="108372">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="106" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>ExSpirit has all the capabilities of Combine, has been around for 2 years at this point, is faster than Combine</p>
</blockquote>
</aside>
<p>Our parser is currently one of the most stable parts of our code. It works well for us, and I don’t see the need to switch to another parser lib (even though I’m not completely happy with combine). That said, if we were to switch to something else, I’d explore other venues, most notably rolling our own parser library, instead of using ex_spirit or nimble_parsec. There are two main reasons for this.</p>
<p>First, parsing speed is absolutely irrelevant for us. We spend much more time executing the query than parsing it. We probably wouldn’t care if our parser is 100x or even 1000x slower.</p>
<p>Another thing is that we’re building AST from tokens, not from bytes or characters. Originally we started by doing a single-pass parsing (i.e. tokenizing and building ast in the same pass), but we quickly found out that this is significantly complicating the parser code. So we split this into two passes, which makes the parser code much easier to follow. Since parsing speed is irrelevant for us, we can afford the luxury of two passes.</p>
<p>My impression is that most available parser libraries today are designed for fast parsing of binary input. That’s definitely a valid target, but it’s not what we need. Therefore, it seems to me that the trade-offs made in such libraries are irrelevant, if not even counter-productive for our particular case. For example, we don’t really need to make any decisions at compile-time, so we don’t care about <code>defparser</code> or similar macros at all. In fact, for our case I’d prefer to have a vanilla combinator which only uses plain functions, not macros.</p>
<p>Most notably, if a parser is forcing us to deal with string input, we probably wouldn’t use it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108372" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/125">Post #124</a>
	                </div>
	            </div>
              <div id="likers-container-108372" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108372"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #124"></div>
  </section>
</div>
    <div class="postbit" id="108399" data-post-id="108399">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>ExSpirit is Great when used as a token parser. You just have to implement a custom combinator, say, <code>satisfies?(predicate)</code> which tests whether the token satisfies a certain predicate or not. I’ve used as a token parser once and it was pretty cool.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108399" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/126">Post #125</a>
	                </div>
	            </div>
              <div id="likers-container-108399" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108399"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #125"></div>
  </section>
</div>
    <div class="postbit" id="108401" data-post-id="108401">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="125" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>Another thing is that we’re building AST from tokens, not from bytes or characters.</p>
</blockquote>
</aside>
<p>That’s actually a pattern that the C++ Spirit supports (it can accept any kind of iterable, not just strings), and my ExSpirit follows the same conventions.  The only things that assume strings are the things in the <code>Text</code> module.  It would be very trivial to create a, oh, <code>Matcher</code> module or token matching (you can create it in user code with ease, a single function would probably work very well, I think C++'s token parsing uses just a single terminal to handle it all).  The main ExSpirit library is agnostic to what is actually being parsed (ignoring a few things like <code>eoi</code> and <code>lexeme</code>that I really should protocolize or at least handle a few erlang-style forms of).  But parsing non-strings was entirely in mind when it was designed.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="sasajuric" data-post="125" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>but we quickly found out that this is significantly complicating the parser code</p>
</blockquote>
</aside>
<p>It absolutely does in most parsers, but you really should try the C++ Spirit design, many modern PEG libraries have copied it’s style for a reason.</p>
<aside class="quote no-group" data-username="sasajuric" data-post="125" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>That’s definitely a valid target, but it’s not what we need.</p>
</blockquote>
</aside>
<p>It’s not always what I need either, like the C++ Spirit library I’ve used to parse bytecode streams, walk and decompose trees, etc…  It is an extremely powerful data transformation library from something that is iterable to something that is structured and vice-versa (so many people miss the nice vice-versa part).  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="tmbb" data-post="126" data-topic="12860" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/t/77aa72/48.png" class="avatar"> tmbb:</div>
<blockquote>
<p>ExSpirit is Great when used as a token parser. You just have to implement a custom combinator, say, <code>satisfies?(predicate)</code> which tests whether the token satisfies a certain predicate or not. I’ve used as a token parser once and it was pretty cool.</p>
</blockquote>
</aside>
<p>Yep this!  It’s really easy to define your own terminals in user-code.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108401" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/127">Post #126</a>
	                </div>
	            </div>
              <div id="likers-container-108401" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108401"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #126"></div>
  </section>
</div>
    <div class="postbit" id="108404" data-post-id="108404">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="OvermindDL1" data-post="127" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/overminddl1/48/2677_2.png" class="avatar"> OvermindDL1:</div>
<blockquote>
<p>It absolutely does in most parsers,</p>
</blockquote>
</aside>
<p>Maybe it’s the lack of a skipper parser?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108404" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/128">Post #127</a>
	                </div>
	            </div>
              <div id="likers-container-108404" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108404"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #127"></div>
  </section>
</div>
    <div class="postbit" id="108411" data-post-id="108411">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="tmbb" data-post="128" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/t/77aa72/48.png" class="avatar"> tmbb:</div>
<blockquote>
<p>Maybe it’s the lack of a skipper parser?</p>
</blockquote>
</aside>
<p>That is such a <em>huge</em> thing that it astounds me that not <em>all</em> language parsers don’t already support such a thing!  o.O</p>
<p>It’s not just the only thing, but yeah, I’d say it’s probably a good 70% of it easy.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108411" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/129">Post #128</a>
	                </div>
	            </div>
              <div id="likers-container-108411" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108411"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #128"></div>
  </section>
</div>
    <div class="postbit" id="108567" data-post-id="108567">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mjadczak" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mjadczak/120/3537_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mjadczak
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For what it’s worth, I’ve been reading through the Spirit docs, and I actually think that there are relatively few core, primitive features missing from NimbleParsec to start approaching that level of functionality (modulo making some particular substructures more efficient, but I think that should come later). Especially once you start looking at X3 and how it uses C++ lambdas for its semantic actions, and how these “context sensitive” parsers are just a special case of the <code>lazy</code> parser (which generates a new parser at runtime), it slowly starts clicking into place. I’m currently knocking the rust off my C++ skills (there’s a Rust pun in there somewhere) and delving into the Spirit code to see how it’s structured internally, and maybe I’ll uncover some ideas for NimbleParsec.</p>
<p>One thing to note is that while Spirit does a lot with C++ syntax, it does have the benefit of having a massively optimising compiler behind it, meaning that the “resultant code” it generates through templating does not have to be so efficient because the C++ compiler will do things like inline functions and unroll loops and optimise accesses etc etc. I think a big point to note with NimbleParsec is that it <em>is</em> itself a compiler of sorts—as much as it’s nice to have functions which return “parsers”, they don’t really return parsers, they return this custom AST (not Elixir AST, NimbleParsec AST) which NimbleParsec then compiles into actual Elixir functions. I’m not sure what the implications of that are yet, but I think it’s useful to keep in mind when thinking of NimbleParsec.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108567" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/130">Post #129</a>
	                </div>
	            </div>
              <div id="likers-container-108567" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108567"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #129"></div>
  </section>
</div>
    <div class="postbit" id="108629" data-post-id="108629">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tmbb" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tmbb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mjadczak" data-post="130" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mjadczak/48/3537_2.png" class="avatar"> mjadczak:</div>
<blockquote>
<p>Especially once you start looking at X3 and how it uses C++ lambdas for its semantic actions, and how these “context sensitive” parsers are just a special case of the <code>lazy</code> parser (which generates a new parser at runtime)</p>
</blockquote>
</aside>
<p>Yeah, context sensitive parsing is just about generating parsers at runtime depending on the data in context map. The tricky part is to optimize that as much as possible. But I believe that NimbleParsec can support it with few changed to the overall architecture.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108629" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/131">Post #130</a>
	                </div>
	            </div>
              <div id="likers-container-108629" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108629"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #130"></div>
  </section>
</div>
    <div class="postbit" id="109315" data-post-id="109315">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mjadczak" data-post="130" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mjadczak/48/3537_2.png" class="avatar"> mjadczak:</div>
<blockquote>
<p>One thing to note is that while Spirit does a lot with C++ syntax, it does have the benefit of having a massively optimising compiler behind it, meaning that the “resultant code” it generates through templating does not have to be so efficient because the C++ compiler will do things like inline functions and unroll loops and optimise accesses etc etc.</p>
</blockquote>
</aside>
<p>Although it does rely on the compiler for that, it generates the code in the type system for in-place generation, thus no intermediary functions, etc…  That means the compiler can optimize it really easily.  In addition there are optimization passes that are ran over the type-tree to optimize certain constructs (via the Proto library it uses behind it).  There is a significant amount of work it does itself to ensure code is generated a very specific way to get the assembly output that they want.</p>
<aside class="quote no-group" data-username="tmbb" data-post="131" data-topic="12860">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/t/77aa72/48.png" class="avatar"> tmbb:</div>
<blockquote>
<p>Yeah, context sensitive parsing is just about generating parsers at runtime depending on the data in context map. The tricky part is to optimize that as much as possible. But I believe that NimbleParsec can support it with few changed to the overall architecture.</p>
</blockquote>
</aside>
<p>+1</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="109315" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/nimbleparsec-a-simple-and-fast-parser-combinator-for-elixir/12860/132">Post #131</a>
	                </div>
	            </div>
              <div id="likers-container-109315" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="109315"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #131"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/12860/load_more?page=14">Load more posts (11 remaining)</a>
</div></template></turbo-stream>