<?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 und kopfschmerzen mit semantic actions]]></title><description><![CDATA[<p>Nabend zusammen!</p>
<p>Ich habe mich seit einigen Tagen mit boost::spirit beschäftigt, und komme momentan an die Grenzen meines Verständnisses.</p>
<p>Es geht darum, eine momentan noch recht simple Konfigurationsdatei zu parsen.<br />
(Bevor ich mich an kommaseparierte Listen wage versuche ich mich zuerst einmal mit einem relativ trivialen Beispiel).</p>
<p>aus dieser zeile möchte ich mit spirit die daten extrahieren, aber mir will es nicht gelingen einen vernünftigen funktor zu konstruieren.</p>
<pre><code>define material red 1 0 0 1 0 0 1 0 0 1
</code></pre>
<p>mein ansatz war bisher:</p>
<pre><code class="language-cpp">typedef struct
{
  float r;
  float g;
  float b;
}
RGB_DATA;

float rgbval;
rule&lt;&gt; _RGBVALUE = longest_d[limit_d(0u, 1u)[int_p[assign_a(rgbval)&rsqb;&rsqb; | limit_d(0.0, 1.0)[real_p[assign_a(rgbval)&rsqb;&rsqb;];
RGB_DATA color;
rule&lt;&gt; _RGB = _RGBVALUE[assign_a(color.r, rgbval)] &gt;&gt; space_p &gt;&gt; _RGBVALUE[assign_a(color.g, rgbval)] &gt;&gt; space_p &gt;&gt; _RGBVALUE[assign_a(color.b, rgbval)];

std::string name;
rule&lt;&gt; _NAME = ((alpha_p) | chlit&lt;&gt;('_')) &gt;&gt; *((alnum_p) | chlit&lt;&gt;('_'));

double exponent;
rule&lt;&gt; _EXPONENT = longest_d[int_p[assign_a(exponent)] | real_p[assign_a(exponent)&rsqb;&rsqb;;

typedef struct
{
  std::string name;
  RGB_DATA ka;
  RGB_DATA kd;
  RGB_DATA ks;
  double exp;
}
MATERIAL_DATA;

MATERIAL_DATA m;
rule&lt;&gt; DEF_MATERIAL = _DEFINE &gt;&gt; space_p &gt;&gt; strlit&lt;&gt;(&quot;material&quot;) &gt;&gt; space_p &gt;&gt; _NAME[assign_a(name)] &gt;&gt; space_p&gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _EXPONENT &gt;&gt; _EOL;
</code></pre>
<p>ab hier stößt meine spielerei mit assign_a() an seine grenzen.<br />
meine versuche einen funktionierenden funktor (nach inspiration der Einführung mit dem INI-Parser) zu schreiben sind kläglich gescheitert. Hat jemand eine Idee wie ich hier weiterkommen kann? Oder kann mich jemand in die richtige Richtung stupsen?</p>
<p>Lieben Gruß</p>
<p>Ike</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/236285/boost-spirit-und-kopfschmerzen-mit-semantic-actions</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 01:24:49 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/236285.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 13 Mar 2009 01:06:08 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to boost::spirit und kopfschmerzen mit semantic actions on Fri, 13 Mar 2009 01:06:08 GMT]]></title><description><![CDATA[<p>Nabend zusammen!</p>
<p>Ich habe mich seit einigen Tagen mit boost::spirit beschäftigt, und komme momentan an die Grenzen meines Verständnisses.</p>
<p>Es geht darum, eine momentan noch recht simple Konfigurationsdatei zu parsen.<br />
(Bevor ich mich an kommaseparierte Listen wage versuche ich mich zuerst einmal mit einem relativ trivialen Beispiel).</p>
<p>aus dieser zeile möchte ich mit spirit die daten extrahieren, aber mir will es nicht gelingen einen vernünftigen funktor zu konstruieren.</p>
<pre><code>define material red 1 0 0 1 0 0 1 0 0 1
</code></pre>
<p>mein ansatz war bisher:</p>
<pre><code class="language-cpp">typedef struct
{
  float r;
  float g;
  float b;
}
RGB_DATA;

float rgbval;
rule&lt;&gt; _RGBVALUE = longest_d[limit_d(0u, 1u)[int_p[assign_a(rgbval)&rsqb;&rsqb; | limit_d(0.0, 1.0)[real_p[assign_a(rgbval)&rsqb;&rsqb;];
RGB_DATA color;
rule&lt;&gt; _RGB = _RGBVALUE[assign_a(color.r, rgbval)] &gt;&gt; space_p &gt;&gt; _RGBVALUE[assign_a(color.g, rgbval)] &gt;&gt; space_p &gt;&gt; _RGBVALUE[assign_a(color.b, rgbval)];

std::string name;
rule&lt;&gt; _NAME = ((alpha_p) | chlit&lt;&gt;('_')) &gt;&gt; *((alnum_p) | chlit&lt;&gt;('_'));

double exponent;
rule&lt;&gt; _EXPONENT = longest_d[int_p[assign_a(exponent)] | real_p[assign_a(exponent)&rsqb;&rsqb;;

typedef struct
{
  std::string name;
  RGB_DATA ka;
  RGB_DATA kd;
  RGB_DATA ks;
  double exp;
}
MATERIAL_DATA;

MATERIAL_DATA m;
rule&lt;&gt; DEF_MATERIAL = _DEFINE &gt;&gt; space_p &gt;&gt; strlit&lt;&gt;(&quot;material&quot;) &gt;&gt; space_p &gt;&gt; _NAME[assign_a(name)] &gt;&gt; space_p&gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _RGB &gt;&gt; space_p &gt;&gt; _EXPONENT &gt;&gt; _EOL;
</code></pre>
<p>ab hier stößt meine spielerei mit assign_a() an seine grenzen.<br />
meine versuche einen funktionierenden funktor (nach inspiration der Einführung mit dem INI-Parser) zu schreiben sind kläglich gescheitert. Hat jemand eine Idee wie ich hier weiterkommen kann? Oder kann mich jemand in die richtige Richtung stupsen?</p>
<p>Lieben Gruß</p>
<p>Ike</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1679074</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1679074</guid><dc:creator><![CDATA[Ike]]></dc:creator><pubDate>Fri, 13 Mar 2009 01:06:08 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit und kopfschmerzen mit semantic actions on Fri, 13 Mar 2009 06:56:04 GMT]]></title><description><![CDATA[<p>Und wo liegt das Problem? Was ist das gewünschte Resultat? Was passiert stattdessen?</p>
<p>IIRC parst real_p auch Integer. Die Unterscheidung in _RGBVALUE und _EXPONENT kannst du dir also sparen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1679106</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1679106</guid><dc:creator><![CDATA[Dasd]]></dc:creator><pubDate>Fri, 13 Mar 2009 06:56:04 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit und kopfschmerzen mit semantic actions on Fri, 13 Mar 2009 13:18:21 GMT]]></title><description><![CDATA[<p>ja, schon klar...<br />
ich verstehe nur nicht wie ich so eine etwas &quot;komplexere&quot; datenstruktur wie MATERIAL_DATA vernünftig gefüllt kriege <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1679321</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1679321</guid><dc:creator><![CDATA[Ike]]></dc:creator><pubDate>Fri, 13 Mar 2009 13:18:21 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit und kopfschmerzen mit semantic actions on Fri, 13 Mar 2009 13:36:40 GMT]]></title><description><![CDATA[<p>Versuchs mal so:</p>
<pre><code class="language-cpp">MATERIAL_DATA m;
rule&lt;&gt; DEF_MATERIAL = _DEFINE &gt;&gt; space_p &gt;&gt; strlit&lt;&gt;(&quot;material&quot;) 
                              &gt;&gt; space_p &gt;&gt; _NAME[assign_a(m.name)] 
                              &gt;&gt; space_p &gt;&gt; _RGB[assign_a(m.ka, color)] 
                              &gt;&gt; space_p &gt;&gt; _RGB[assign_a(m.kd, color)] 
                              &gt;&gt; space_p &gt;&gt; _RGB[assign_a(m.ks, color)]  
                              &gt;&gt; space_p &gt;&gt; _EXPONENT[assign_a(m.exp, exponent)]
                              &gt;&gt; _EOL;
</code></pre>
<p>Und dann evtl. noch die üblichen Konventionen/Vorsichtsmaßnahmen beachten und die führenden unterstriche vermeiden...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1679335</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1679335</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 13 Mar 2009 13:36:40 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit und kopfschmerzen mit semantic actions on Fri, 13 Mar 2009 13:43:10 GMT]]></title><description><![CDATA[<p>Ich habe mir dafür dann extra Parser geschrieben, die einen entsprechenden<br />
Resulttype hatten. Da kannst du dann auch einfach assign_a auf einen komplexeren Datentyp anwenden (sofern Assignment unterstützt wird).</p>
<p>Zum Beispiel folgende Datenstruktur:</p>
<pre><code class="language-cpp">const unsigned int RGB = 0;
const unsigned int GRAY = 1;

struct Color {
	unsigned int type;
	unsigned char c1, c2, c3;

	Color() : type(RGB), c1(0), c2(0), c3(0) { }

	Color(unsigned int type, unsigned char c1, unsigned char c2, unsigned char c3) : type(type), c1(c1), c2(c2), c3(c3) { }
};
</code></pre>
<p>Dann hatte ich dafür folgenden Parser:</p>
<pre><code class="language-cpp">struct ColorParser : public boost::spirit::parser&lt;ColorParser&gt; {
	typedef ColorParser self_t;

	template&lt;typename ScannerT&gt;
	struct result {
		typedef	typename boost::spirit::match_result&lt;ScannerT, Color&gt;::type type;
	};

	template &lt;typename ScannerT&gt;
	typename boost::spirit::parser_result&lt;self_t, ScannerT&gt;::type
	parse(ScannerT const&amp; scan) const {
		using namespace boost::spirit;

		typedef typename ScannerT::iterator_t Iterator;
		typedef typename boost::spirit::parser_result&lt;self_t, ScannerT&gt;::type ResultType;

		Color color;
		Iterator save = scan.first;

	    ResultType result = (
			(str_p(&quot;RGB(&quot;)[assign_a(color.type, RGB)]
					&gt;&gt; limit_d(0u, 255u)[uint_p[assign_a(color.c1)&rsqb;&rsqb; &gt;&gt; &quot;,&quot;
					&gt;&gt; limit_d(0u, 255u)[uint_p[assign_a(color.c2)&rsqb;&rsqb; &gt;&gt; &quot;,&quot;
					&gt;&gt; limit_d(0u, 255u)[uint_p[assign_a(color.c3)&rsqb;&rsqb; &gt;&gt; &quot;)&quot;)
			|
			(str_p(&quot;GRAY(&quot;)[assign_a(color.type, GRAY)]
					&gt;&gt; limit_d(0u, 255u)[uint_p[assign_a(color.c1)&rsqb;&rsqb; &gt;&gt; &quot;)&quot;)
	    ).parse(scan);

		if (result) {
		    return match&lt;Color&gt;(result.length(), color);
		}
	    scan.first = save;
		return scan.no_match();
	}
};

const ColorParser color_p = ColorParser();
</code></pre>
<p>Einsetzen kann man sowas dann (sinngemäß) wiefolgt:</p>
<pre><code class="language-cpp">Color c1, c2;
parse(&quot;RGB(255, 0, 0) GRAY(192)&quot;, color_p[assign_a(c1)] &gt;&gt; color_p[assign_a(c2)], space_p);
</code></pre>
<p>Leider ließen sich die Farbtypen nicht als Enums festlegen, assign_a hat dann immer irgendwelche unsinnigen Werte zugewiesen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1679340</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1679340</guid><dc:creator><![CDATA[Dasd]]></dc:creator><pubDate>Fri, 13 Mar 2009 13:43:10 GMT</pubDate></item></channel></rss>