<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="109319" data-post-id="109319">
  <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><a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a> would you be open to changing the “parser AST” in order to include metadata information that could e used with my <code>combinators/1</code> macro?</p>
<p>Edit: typo</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="109319" 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/133">Post #132</a>
	                </div>
	            </div>
              <div id="likers-container-109319" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="109319"
                     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 #132"></div>
  </section>
</div>
    <div class="postbit" id="109479" data-post-id="109479">
  <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">
								<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>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>
</blockquote>
</aside>
<p>I think that what I was thinking here was that in the case of C++, returning a parser “dynamically” is not extremely different from having a “static” one—all it is is a closure with the same code as for the “static” case, just with the compiler providing some bindings for some variables transparently and then populating those variables at runtime. That’s because all of the code is going through the same compiler—the C++ compiler.</p>
<p>In NimbleParsec’s case, the <code>defparsec</code> macro <em>is</em> in itself a compiler. Unless it’s somehow possible to move its logic higher up somehow (e.g. as a <code>mix</code> compiler) so that it can “transparently” act on code inside “dynamic” <code>fn</code>s (i.e. inside closures), I think the “right” way to implement this is not to have worse-performing dynamic-style parsecs, but rather to empower NimbleParsec to also transform <code>fn x, y, z -&gt; parsec</code> into a real piece of the optimised NimbleParsec code, but tracking all of the bindings to <code>x</code>, <code>y</code> and <code>z</code> and actually injecting them into the real generated code—essentially what the compiler does anyway when constructing closures.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="109479" 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/134">Post #133</a>
	                </div>
	            </div>
              <div id="likers-container-109479" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="109479"
                     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 #133"></div>
  </section>
</div>
    <div class="postbit" id="109482" data-post-id="109482">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sure. Can you do a quick and small PR that changes one or two combinators, as an example? And once we agree on the shape we can change the rest.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="109482" data-batch-url="/posts/batch_likers">
                        2
                      </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/135">Post #134</a>
	                </div>
	            </div>
              <div id="likers-container-109482" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="109482"
                     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 #134"></div>
  </section>
</div>
    <div class="postbit" id="109755" data-post-id="109755">
  <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>I thought it would be easy to make some minimal changes in NimbleParsec without understanding the whole codebase, but it hasn’t proved easy at all. I’ll have to take some time to understand it better before I can change anything.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="109755" 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/136">Post #135</a>
	                </div>
	            </div>
              <div id="likers-container-109755" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="109755"
                     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 #135"></div>
  </section>
</div>
    <div class="postbit" id="176122" data-post-id="176122">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Our frontend is implementing a custom language for users to query data (simpler than SQL). I am wondering if NimbleParsec has a way that could help me provide “autocomplete” like functionality.</p>
<p>For example, a user types  <code>if points</code>  and then an autocomplete would pop-up with a list of next possible tokens such as  <code>["&gt;", "&lt;", "="]</code> .</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="176122" 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/137">Post #136</a>
	                </div>
	            </div>
              <div id="likers-container-176122" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="176122"
                     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 #136"></div>
  </section>
</div>
    <div class="postbit" id="190493" data-post-id="190493">
  <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>I’m trying to write a parser combinator that matches (and consumes) a regex at the beginning of the input string. For example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RegexParserExample do
  import NimbleParsec
  import RegexParsec
  # Parses javascript-style inline comments
  comment = regex(~r[//(.*?)\n])
  defparsec(:comment, comment)
end
</code></pre>
<p>The closest I have come is the following, using the <code>post_traverse</code> combinator:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RegexParsec do
  import NimbleParsec

  def regex(combinator \\ empty(), %Regex{} = re) do
    anchored_re = Regex.compile!("^" &lt;&gt; re.source, re.opts)
    post_traverse(combinator, {__MODULE__, :__regex__, [anchored_re]})
  end

  def __regex__(input, args, context, _line, _offset, re) do
    case Regex.run(re, input) do
      [bin | _] -&gt;
        length = byte_size(bin)
        &lt;&lt; _part :: binary-size(length), _rest :: binary &gt;&gt; = input
        # Doesn't consume input!
        {[bin | args], context}

      nil -&gt;
        {:error, "doesn't match regex #{inspect(re)}"}
    end
  end
end
</code></pre>
<p>The problem is that none of the <code>*_traverse</code> combinators allow me to to actually <em>consume</em> the input. They can only transform a result that comes from another parser, but not consume new bytes from the input string. The only way I can think of doing this is by having my parser return a parsec, but I’m not sure how to keep the context in a custom parsec (I don’t actually think any parser out there is actually using the context, but still).</p>
<p>I don’t know if even this possibility is recommended, because I don’t think there’s an API to add parsecs aside from the obvious one.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="190493" 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/138">Post #137</a>
	                </div>
	            </div>
              <div id="likers-container-190493" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="190493"
                     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 #137"></div>
  </section>
</div>
    <div class="postbit" id="190506" data-post-id="190506">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Can the new lookahead stuff be used for this? First you look ahead and then you parse if it matches.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="190506" 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/139">Post #138</a>
	                </div>
	            </div>
              <div id="likers-container-190506" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="190506"
                     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 #138"></div>
  </section>
</div>
    <div class="postbit" id="190508" data-post-id="190508">
  <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>I can look ahead just fine, the problem is actually consuming the input. I’d need something like a combinator that would see how many bytes the regex matched and then advance that number of bytes in the string. I’ve actually found a solution that depends on creating a custom parsec from scratch, but it’s not the most elegant:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule RegexParsec do
  import NimbleParsec

  defmacro defregexparsec(name, re) do
    {evaluated_re, _} = Code.eval_quoted(re)
    anchored_re = Regex.compile!("^" &lt;&gt; evaluated_re.source, evaluated_re.opts)
    escaped_re = Macro.escape(anchored_re)
    name__0 = String.to_atom(Atom.to_string(name) &lt;&gt; "__0")

    quote do
      def unquote(name)(input) do
        unquote(name__0)(input, [], [], %{}, {1, 0}, 0)
      end

      def unquote(name__0)(input, acc, stack, context, {line, offset}, column) do
        case Regex.run(unquote(escaped_re), input) do
          [bin | _] -&gt;
            length = byte_size(bin)
            # Split the string in two parts; keep the second part
            &lt;&lt;_part::binary-size(length), rest::binary&gt;&gt; = input
            # How many lines have we advanced?
            lines = String.split("\n")
            delta_lines = length(lines)
            # The column is the byte offset of the last line (I think?)
            new_column =
              case lines do
                [] -&gt; 0
                _ -&gt; lines |&gt; List.last() |&gt; byte_size()
              end

            # I hope I'm returning the right format?
            {:ok, [bin | acc], rest, context, {line + delta_lines, new_column}, column + length}

          nil -&gt;
            {:error, unquote("expected to match regex #{inspect(evaluated_re)}"), input, context,
             {line, offset}, column}
        end
      end
    end
  end
end

defmodule RegexParserExample do
  import NimbleParsec
  import RegexParsec

  defregexparsec(:comment, ~r[//(.*?)\n])
  defparsec(:comments, repeat(parsec(:comment)))
end
</code></pre>
<p>It depends on some implementation details, of nimble_parsec, but it seems to work.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="190508" 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/140">Post #139</a>
	                </div>
	            </div>
              <div id="likers-container-190508" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="190508"
                     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 #139"></div>
  </section>
</div>
    <div class="postbit" id="219553" data-post-id="219553">
  <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>In case someone might actually think of using it, be aware that this approach is veeeery slow… Matching regexes in the middle of a parsec is a big “No” for performance. An interesting alternative would be to compile a regex to NimbleParsec combinators, but that seems more work than it’s worth.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="219553" 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/141">Post #140</a>
	                </div>
	            </div>
              <div id="likers-container-219553" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="219553"
                     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 #140"></div>
  </section>
</div>
    <div class="postbit" id="268265" data-post-id="268265">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sorry to resurrect an old thread.</p>
<p>Is nimble parsec an appropriate tool for the frontend of a compiler? Or is it really just better to roll one’s own Lexer and parser, I understand that the latter give you the most freedom (and the most foot guns.)</p>
<p>For example, how does one idiomatically eliminate left recursion using this library?</p>
<p>Thanks!<br>
Joe</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="268265" 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/142">Post #141</a>
	                </div>
	            </div>
              <div id="likers-container-268265" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="268265"
                     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 #141"></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=15">Load more posts (1 remaining)</a>
</div></template></turbo-stream>