<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[boost::spirit - semantic action parameter type?]]></title><description><![CDATA[<p>Hallo <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich versuche seit etlichen Stunden einen kleinen Parser mittels boost::spirit (Version 2.5.3, Visual Studio 2015) zu schreiben. Ich möchte mittels den &quot;semantic actions&quot; die iteratorposition extrahieren. Dazu lege ich mir einen functor welcher im ()-operator den aktuellen iterator speichern soll. Jedoch war ich nicht in der Lage den Typ der Argumente herauszufinden.</p>
<p>Beispielsregel:</p>
<pre><code>struct LineCounter
{
	LineCounter(Assembler::iterator &amp;ref, unsigned &amp;num) : iter(ref), line(num)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
		iter = &amp;val;
		++line;
	}
	unsigned &amp;line;
	Assembler::iterator &amp;iter;
};

char newline = '\n';
rule space = (qi::space - qi::char_(newline)) | qi::char_(newline)[LineCounter(line_beginning, current_line)];
</code></pre>
<p>Dieses Beispiel kompiliert wunderbar. Anscheinend übergibt ein qi::char_ eine referenz auf const char.</p>
<p>Das selbe klappt bei komplexeren Regeln aber nicht mehr:</p>
<pre><code>struct SaveIterator
{
	SaveIterator(Assembler::iterator &amp;ref) : iter(ref)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
	}
	Assembler::iterator &amp;iter;
};
struct AddInstruction
{
	AddInstruction(std::list&lt;Instruction&gt; &amp;list, Assembler::iterator &amp;ref) : instructions(list), iter(ref)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
	}
	std::list&lt;Instruction&gt; &amp;instructions;
	Assembler::iterator &amp;iter;
};

rule zero_operand_instruction = *space &gt;&gt; zero_operand_mnemonic[SaveIterator(saved_iterator)] &gt;&gt; eps[AddInstruction(instructions, saved_iterator)] &gt;&gt; *space;
</code></pre>
<p>Die Compiler-Fehlermeldung ist zwar vorhanden, hilft aber nicht weiter</p>
<pre><code>1&gt;c:\program files (x86)\boost\include\boost-1_58\boost\spirit\home\support\action_dispatch.hpp(142): error C2893: Failed to specialize function template 'action_dispatch&lt;Subject&gt;::fwd_storage&lt;unknown-type,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_attrib_context_pass&gt;::type boost::spirit::traits::action_dispatch&lt;Subject&gt;::do_call(F &amp;&amp;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;A&gt;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;B&gt;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;C&gt;,...)'
1&gt;          with
1&gt;          [
1&gt;              Subject=boost::spirit::qi::reference&lt;const boost::spirit::qi::rule&lt;Assembler::iterator,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type&gt;&gt;
1&gt;          ]
</code></pre>
<p>Eigentlich wäre ich davon ausgegangen dass zumindest eps als typ einen const char &amp; übergibt. Ich habe bereits allerlei typen getestet:<br />
const char &amp;<br />
const char *<br />
std::string::iterator<br />
std::string::const_iterator<br />
std::string::const_iterator &amp;</p>
<p>Welche Typen bekommen die beiden functoren übergeben? Und wo finde ich eine Referenz dazu? Habe bereits mehrere Boost-beispiele durchgearbeitet, diese beschränken sich darauf einen bequemen int&amp; von dem int_ objekt abzuholen. Auch suchen brachte mir nichts <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Und:</p>
<p>Kann man das ganze Konstrukt vielleicht schöner schreiben? Ich will eigentlich nur die Start und Endposition der gematchten Regel. Gibt es keine Möglichkeit den functor mit</p>
<pre><code>void operator () (const std::string::const_iterator &amp;beg, const std::string::const_iterator &amp;end, qi::unused_type);
</code></pre>
<p>zu deklarieren? Dann könnte man direkt mit den Iteratoren arbeiten.</p>
<p>-- MemoryPool</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/333780/boost-spirit-semantic-action-parameter-type</link><generator>RSS for Node</generator><lastBuildDate>Sun, 26 Apr 2026 11:37:54 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/333780.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 31 Jul 2015 03:47:08 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to boost::spirit - semantic action parameter type? on Fri, 31 Jul 2015 03:47:08 GMT]]></title><description><![CDATA[<p>Hallo <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Ich versuche seit etlichen Stunden einen kleinen Parser mittels boost::spirit (Version 2.5.3, Visual Studio 2015) zu schreiben. Ich möchte mittels den &quot;semantic actions&quot; die iteratorposition extrahieren. Dazu lege ich mir einen functor welcher im ()-operator den aktuellen iterator speichern soll. Jedoch war ich nicht in der Lage den Typ der Argumente herauszufinden.</p>
<p>Beispielsregel:</p>
<pre><code>struct LineCounter
{
	LineCounter(Assembler::iterator &amp;ref, unsigned &amp;num) : iter(ref), line(num)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
		iter = &amp;val;
		++line;
	}
	unsigned &amp;line;
	Assembler::iterator &amp;iter;
};

char newline = '\n';
rule space = (qi::space - qi::char_(newline)) | qi::char_(newline)[LineCounter(line_beginning, current_line)];
</code></pre>
<p>Dieses Beispiel kompiliert wunderbar. Anscheinend übergibt ein qi::char_ eine referenz auf const char.</p>
<p>Das selbe klappt bei komplexeren Regeln aber nicht mehr:</p>
<pre><code>struct SaveIterator
{
	SaveIterator(Assembler::iterator &amp;ref) : iter(ref)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
	}
	Assembler::iterator &amp;iter;
};
struct AddInstruction
{
	AddInstruction(std::list&lt;Instruction&gt; &amp;list, Assembler::iterator &amp;ref) : instructions(list), iter(ref)
	{
	}
	void operator () (const char &amp;val, qi::unused_type, qi::unused_type) const
	{
	}
	std::list&lt;Instruction&gt; &amp;instructions;
	Assembler::iterator &amp;iter;
};

rule zero_operand_instruction = *space &gt;&gt; zero_operand_mnemonic[SaveIterator(saved_iterator)] &gt;&gt; eps[AddInstruction(instructions, saved_iterator)] &gt;&gt; *space;
</code></pre>
<p>Die Compiler-Fehlermeldung ist zwar vorhanden, hilft aber nicht weiter</p>
<pre><code>1&gt;c:\program files (x86)\boost\include\boost-1_58\boost\spirit\home\support\action_dispatch.hpp(142): error C2893: Failed to specialize function template 'action_dispatch&lt;Subject&gt;::fwd_storage&lt;unknown-type,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_attrib_context_pass&gt;::type boost::spirit::traits::action_dispatch&lt;Subject&gt;::do_call(F &amp;&amp;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;A&gt;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;B&gt;,boost::spirit::traits::action_dispatch&lt;Subject&gt;::fwd_tag&lt;C&gt;,...)'
1&gt;          with
1&gt;          [
1&gt;              Subject=boost::spirit::qi::reference&lt;const boost::spirit::qi::rule&lt;Assembler::iterator,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type,boost::spirit::unused_type&gt;&gt;
1&gt;          ]
</code></pre>
<p>Eigentlich wäre ich davon ausgegangen dass zumindest eps als typ einen const char &amp; übergibt. Ich habe bereits allerlei typen getestet:<br />
const char &amp;<br />
const char *<br />
std::string::iterator<br />
std::string::const_iterator<br />
std::string::const_iterator &amp;</p>
<p>Welche Typen bekommen die beiden functoren übergeben? Und wo finde ich eine Referenz dazu? Habe bereits mehrere Boost-beispiele durchgearbeitet, diese beschränken sich darauf einen bequemen int&amp; von dem int_ objekt abzuholen. Auch suchen brachte mir nichts <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>Und:</p>
<p>Kann man das ganze Konstrukt vielleicht schöner schreiben? Ich will eigentlich nur die Start und Endposition der gematchten Regel. Gibt es keine Möglichkeit den functor mit</p>
<pre><code>void operator () (const std::string::const_iterator &amp;beg, const std::string::const_iterator &amp;end, qi::unused_type);
</code></pre>
<p>zu deklarieren? Dann könnte man direkt mit den Iteratoren arbeiten.</p>
<p>-- MemoryPool</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2461758</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2461758</guid><dc:creator><![CDATA[MemoryPool]]></dc:creator><pubDate>Fri, 31 Jul 2015 03:47:08 GMT</pubDate></item></channel></rss>