<?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 Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling]]></title><description><![CDATA[<p>Hallo miteinander,</p>
<p>ich habe mit in die Dokumentation von boost eingelesen und will nun meinen selbstentwickelten Compiler für boost umschreiben, habe jedoch Probleme, die ich darauf zurückführe, dass es Probleme bei einer Rekursion gibt. Hier jedoch erstmal ein einfacher Testcode, der folgende Grammatik unterstützen <em>sollte.</em></p>
<pre><code>nondigit   ::= ( ALPHA_CHARACTER | '_' ).
digit      ::= DIGIT.
identifier ::= ( nondigit | identifier nondigit | identifier digit ).
</code></pre>
<pre><code class="language-cpp">#include &lt;boost\spirit.hpp&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

using namespace boost::spirit;

#define ALPHA_CHARACTER (range&lt;&gt;('a', 'z') | range&lt;&gt;('A', 'Z') | chlit&lt;&gt;('$'))
#define DIGIT (chlit&lt;&gt;('0') | chlit&lt;&gt;('1') | chlit&lt;&gt;('2') | chlit&lt;&gt;('3') | chlit&lt;&gt;('4') | chlit&lt;&gt;('5') | chlit&lt;&gt;('6') | chlit&lt;&gt;('7') | chlit&lt;&gt;('8') | chlit&lt;&gt;('9'))

int main(int argc, char** argv)
{
	rule&lt;&gt; nondigit_p = (ALPHA_CHARACTER | chlit&lt;&gt;('_'));
	rule&lt;&gt; digit_p = DIGIT;
	rule&lt;&gt; identifier_p = (nondigit_p | (identifier_p &gt;&gt; nondigit_p) | (identifier_p &gt;&gt; digit_p));

	std::string str;
	while(getline(std::cin, str)) {
		if(str.empty() || str[0] == 'q' || str[0] == 'Q')
			break;

		if(parse(str.c_str(), identifier_p).full) {
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
			std::cout &lt;&lt; &quot;Parsing succeeded\n&quot;;
			std::cout &lt;&lt; str &lt;&lt; &quot; Parses OK: &quot; &lt;&lt; std::endl;
		}
		else {
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
			std::cout &lt;&lt; &quot;Parsing failed\n&quot;;
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
		}
	}

	std::cout &lt;&lt; &quot;Bye... :-) \n\n&quot;;
    return 0;
}
</code></pre>
<p>Leider funktioniert nur die Eingabe von '_', '$', einem beliebigen char aus A..Za..z, aber wenn ich bloß eine Ziffer eingebe, stürzt das Programm ab und bei einem Text von zwei Zeichen (egal ob char oder mit Ziffer) wird die Eingabe nicht geparsed!</p>
<p>Eine Ahnung, was das Problem sein könnte und wie es zu beheben ist?</p>
<p>Gruß,<br />
Christian</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/279493/boost-spirit-rekursions-probleme-gelöst-neu-probleme-beim-file-handling</link><generator>RSS for Node</generator><lastBuildDate>Mon, 24 Aug 2026 12:20:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/279493.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 27 Dec 2010 21:30:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Thu, 30 Dec 2010 09:24:32 GMT]]></title><description><![CDATA[<p>Hallo miteinander,</p>
<p>ich habe mit in die Dokumentation von boost eingelesen und will nun meinen selbstentwickelten Compiler für boost umschreiben, habe jedoch Probleme, die ich darauf zurückführe, dass es Probleme bei einer Rekursion gibt. Hier jedoch erstmal ein einfacher Testcode, der folgende Grammatik unterstützen <em>sollte.</em></p>
<pre><code>nondigit   ::= ( ALPHA_CHARACTER | '_' ).
digit      ::= DIGIT.
identifier ::= ( nondigit | identifier nondigit | identifier digit ).
</code></pre>
<pre><code class="language-cpp">#include &lt;boost\spirit.hpp&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

using namespace boost::spirit;

#define ALPHA_CHARACTER (range&lt;&gt;('a', 'z') | range&lt;&gt;('A', 'Z') | chlit&lt;&gt;('$'))
#define DIGIT (chlit&lt;&gt;('0') | chlit&lt;&gt;('1') | chlit&lt;&gt;('2') | chlit&lt;&gt;('3') | chlit&lt;&gt;('4') | chlit&lt;&gt;('5') | chlit&lt;&gt;('6') | chlit&lt;&gt;('7') | chlit&lt;&gt;('8') | chlit&lt;&gt;('9'))

int main(int argc, char** argv)
{
	rule&lt;&gt; nondigit_p = (ALPHA_CHARACTER | chlit&lt;&gt;('_'));
	rule&lt;&gt; digit_p = DIGIT;
	rule&lt;&gt; identifier_p = (nondigit_p | (identifier_p &gt;&gt; nondigit_p) | (identifier_p &gt;&gt; digit_p));

	std::string str;
	while(getline(std::cin, str)) {
		if(str.empty() || str[0] == 'q' || str[0] == 'Q')
			break;

		if(parse(str.c_str(), identifier_p).full) {
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
			std::cout &lt;&lt; &quot;Parsing succeeded\n&quot;;
			std::cout &lt;&lt; str &lt;&lt; &quot; Parses OK: &quot; &lt;&lt; std::endl;
		}
		else {
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
			std::cout &lt;&lt; &quot;Parsing failed\n&quot;;
			std::cout &lt;&lt; &quot;-------------------------\n&quot;;
		}
	}

	std::cout &lt;&lt; &quot;Bye... :-) \n\n&quot;;
    return 0;
}
</code></pre>
<p>Leider funktioniert nur die Eingabe von '_', '$', einem beliebigen char aus A..Za..z, aber wenn ich bloß eine Ziffer eingebe, stürzt das Programm ab und bei einem Text von zwei Zeichen (egal ob char oder mit Ziffer) wird die Eingabe nicht geparsed!</p>
<p>Eine Ahnung, was das Problem sein könnte und wie es zu beheben ist?</p>
<p>Gruß,<br />
Christian</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1999481</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999481</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 30 Dec 2010 09:24:32 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Tue, 28 Dec 2010 00:29:16 GMT]]></title><description><![CDATA[<p>Ich weiß nicht, ob boost::spirit rekursive Regeln unterstützt. Warum formulierst du <em>identifier_p</em> nicht als *nondigit_p &gt;&gt; <em>(nondigit_p | digit_p)</em> ?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1999518</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999518</guid><dc:creator><![CDATA[wx++]]></dc:creator><pubDate>Tue, 28 Dec 2010 00:29:16 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Tue, 28 Dec 2010 07:43:54 GMT]]></title><description><![CDATA[<p>Ich wollte in meiner EBNF-Notation Kleene-Sterne weglassen, wie es auch in der C++-EBNF-Notation der Fall ist. Aber dein Vorschlag ist ja logisch und klappt. D.h. ich werde wohl oder über, nachher bei komplexen Regeln, die auf sich selber verweisen bisschen tricksen müssen, wenn es dazu kommen sollte <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Mit 2 Promille ist es auch schwer gewesen darauf zu kommen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /> Aber danke nochmal.</p>
<p>Gruß,<br />
Christian</p>
<p>PS: Wenn ich wieder dieses Problem habe, werde ich diesen Topic einfach pushen und neu nachfragen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1999542</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999542</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 28 Dec 2010 07:43:54 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Tue, 28 Dec 2010 23:07:30 GMT]]></title><description><![CDATA[<p>Du hast dort eine <em>links</em>rekursion. Die kann spirit nicht, weil das ein linksrekursiver Parser ist. rechts-rekursionen sind aber kein Problem. DU musst also dafür sorgen, dass du immer mindestens ein echtes Zeichen ließt, bevor du eine Rekursionsebene tiefer gehst.</p>
<p>Sonst macht Spirit das:</p>
<pre><code>identifier-&gt;nondigit (false)
identifier-&gt;identifier
    identifier-&gt;nondigit(false)
    identifier-&gt;identifier
        identifier-&gt;nondigit (false)
        identifier-&gt;identifier
//usw
</code></pre>
<p>man kann übrigens jede Linksrekursion entfernen. In diesem Fall mit dem Kleene-Stern, oder direkt mit einer rechtsrekursion.</p>
<pre><code>identifier ::= ( nondigit | nondigit identifier | digit identifier)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1999820</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999820</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Tue, 28 Dec 2010 23:07:30 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Wed, 29 Dec 2010 08:57:05 GMT]]></title><description><![CDATA[<p>Danke für den Hinweis. Beim Durchsuchen meiner Vorlesungsfolien (Theoretische Informatik) habe ich so einen ähnlichen Zusammenhang/Sachverhalt gefunden. Da sieht man, wie gut es doch ist, vieles aufzuheben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>// EDIT: Ich habe eh etwas aufgeräumt (wenn auch noch nicht ganz gut) und mit Funktoren gespielt. Hier zudem meine (unvollständige) Grammatik, die unten implementiert ist.</p>
<pre><code>identifier                      ::= ( nondigit | identifier nondigit | identifier digit ).
nondigit                        ::= ( ALPHA_CHARACTER | '_' ).
digit                           ::= DIGIT.
syntax                          ::= [ translation_unit ].
translation_unit                ::= [ declaration_seq ].
declaration_seq                 ::= ( declaration | declaration_seq declaration ).
declaration                     ::= ( explicit_instantiation | explicit_specialization | namespace_definition ).
namespace_definition            ::= ( named_namespace_definition | unnamed_namespace_definition ).
unnamed_namespace_definition    ::= 'namespace' '{' namespace_body '}'.
named_namespace_definition      ::= ( original_namespace_definition | extension_namespace_definition ).
original_namespace_definition   ::= 'namespace' identifier '{' namespace_body '}'.
extension_namespace_definition  ::= 'namespace' original_namespace_name '{' namespace_body '}'.
original_namespace_name         ::= identifier.
namespace_body                  ::= [ declaration_seq ].
explicit_instantiation          ::= 'template' declaration.
explicit_specialization         ::= 'template' '&lt;' '&gt;' declaration.
</code></pre>
<pre><code class="language-cpp">#define ALPHA_CHARACTER (alpha_p | chlit&lt;&gt;('$'))
#define DIGIT (range&lt;&gt;('0', '9'))

namespace fpp {
	namespace compiler {
		namespace spirit {
			namespace functors {
				struct __namespace {
					template&lt;typename IteratorT&gt;
					void operator()(IteratorT begin, IteratorT end) const {
						std::cout &lt;&lt; &quot;Found a namespace '&quot; &lt;&lt; std::string(begin, end) &lt;&lt; &quot;'.&quot; &lt;&lt; std::endl;
					}
				};

				struct __unnamed_namespace {
					template&lt;typename IteratorT&gt;
					void operator()(IteratorT begin, IteratorT end) const {
						std::cout &lt;&lt; &quot;Found an unnamed/anonymous namespace.&quot; &lt;&lt; std::endl;
					}
				};

				struct __explicit_template {
					template&lt;typename IteratorT&gt;
					void operator()(IteratorT begin, IteratorT end) const {
						std::cout &lt;&lt; &quot;Explicit template declaration.&quot; &lt;&lt; std::endl;
					}
				};
			}

			struct fpp_grammar : public grammar&lt;fpp_grammar&gt; {
				template&lt;class ScannerT&gt;
				struct definition {
					rule&lt;ScannerT&gt; nondigit_p;
					rule&lt;ScannerT&gt; digit_p;
					rule&lt;ScannerT&gt; identifier_p;

					rule&lt;ScannerT&gt; explicit_instantiation_p;
					rule&lt;ScannerT&gt; explicit_specialization_p;

					rule&lt;ScannerT&gt; namespace_body_p;
					rule&lt;ScannerT&gt; original_namespace_name_p;
					rule&lt;ScannerT&gt; extension_namespace_definition_p;
					rule&lt;ScannerT&gt; original_namespace_definition_p;
					rule&lt;ScannerT&gt; named_namespace_definition_p;
					rule&lt;ScannerT&gt; unnamed_namespace_definition_p;
					rule&lt;ScannerT&gt; namespace_definition_p;
					rule&lt;ScannerT&gt; declaration_p;
					rule&lt;ScannerT&gt; declaration_seq_p;
					rule&lt;ScannerT&gt; translation_unit_p;
					rule&lt;ScannerT&gt; syntax_p;

					definition(const fpp_grammar &amp;self) {
						nondigit_p = (ALPHA_CHARACTER | chlit&lt;&gt;('_'));
						digit_p = DIGIT;
						identifier_p = nondigit_p &gt;&gt; *(nondigit_p | digit_p);

						explicit_instantiation_p = strlit&lt;&gt;(&quot;template&quot;) &gt;&gt; declaration_p;
						explicit_specialization_p = strlit&lt;&gt;(&quot;template&quot;) &gt;&gt; chlit&lt;&gt;('&lt;') &gt;&gt; chlit&lt;&gt;('&gt;') &gt;&gt; declaration_p;

						namespace_body_p = !declaration_seq_p;
						original_namespace_name_p = identifier_p;
						extension_namespace_definition_p = strlit&lt;&gt;(&quot;namespace&quot;) &gt;&gt; original_namespace_name_p[functors::__namespace()] &gt;&gt; chlit&lt;&gt;('{') &gt;&gt; namespace_body_p &gt;&gt; chlit&lt;&gt;('}');
						original_namespace_definition_p = strlit&lt;&gt;(&quot;namespace&quot;) &gt;&gt; identifier_p[functors::__namespace()] &gt;&gt; chlit&lt;&gt;('{') &gt;&gt; namespace_body_p &gt;&gt; chlit&lt;&gt;('}');
						named_namespace_definition_p = (original_namespace_definition_p | extension_namespace_definition_p);
						unnamed_namespace_definition_p = strlit&lt;&gt;(&quot;namespace&quot;) &gt;&gt; chlit&lt;&gt;('{') &gt;&gt; namespace_body_p &gt;&gt; chlit&lt;&gt;('}');
						namespace_definition_p = (named_namespace_definition_p | unnamed_namespace_definition_p[functors::__unnamed_namespace()]);
						declaration_p = (explicit_instantiation_p[functors::__explicit_template()] | explicit_specialization_p[functors::__explicit_template()] | namespace_definition_p);
						declaration_seq_p = declaration_p &gt;&gt; *(declaration_p);
						translation_unit_p = !declaration_seq_p;
						syntax_p = translation_unit_p;
					}

					rule&lt;ScannerT&gt; const &amp;start() {
						return syntax_p;
					}
				};
			};
		}
	}
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1999879</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999879</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 29 Dec 2010 08:57:05 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Wed, 29 Dec 2010 12:34:32 GMT]]></title><description><![CDATA[<p>lass mal doppelte &quot;_&quot; am Anfang von Namen weg. Diese Namen sind für die Compiler reserviert. Insbesondere bei Namen wie __namespace wäre ich ganz besonders vorsichtig...</p>
<p>Auch empfinde ich so tief geschachtelte Namensräume hässlich, aber das ist ja jedem selbst überlassen...</p>
<p>die Makros brauchst du aber auch nicht, stattdessen kannst du eine passende Regel dafür anlegen, kommt am Ende auf das Selbe raus. Ansonsten erinnert mich der Code daran, warum ich spirit als unglaublich hässlich empfand...arrgh.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1999967</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999967</guid><dc:creator><![CDATA[otze]]></dc:creator><pubDate>Wed, 29 Dec 2010 12:34:32 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Wed, 29 Dec 2010 12:45:33 GMT]]></title><description><![CDATA[<p>Das mit den Makros kommt ja noch aus meinem ersten Versuch nachts um wieviel Uhr auch immer mit 2 Promille <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="🙂"
    /><br />
Spirit ist etwas unschön geworden bei mir, weil ich jetzt zahlreiche Regeln eingebaut habe und alles unleserlich geworden ist, aber immerhin einfacher als mein erster Versuch, wo ich Zeichen für Zeichen geparsed habe! Nun kann man ja auch sprachneutral in alle anderen Sprachen umschreiben <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_tongue"
      title=":P"
      alt="😛"
    /></p>
<p>Diese tiefgeschachtelten Namespaces bin ich aus C# gewohnt und die sind eh nicht öffentlich, weil sie ja eh nur im Scanner/Parser sind <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1999969</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1999969</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Wed, 29 Dec 2010 12:45:33 GMT</pubDate></item><item><title><![CDATA[Reply to boost::spirit Rekursions-Probleme [gelöst] + [neu] Probleme beim File Handling on Thu, 30 Dec 2010 09:29:11 GMT]]></title><description><![CDATA[<p>Einen Schritt weiter, mehr Probleme!<br />
Bisher habe ich meinen Test-Code, der geparsed werden soll, über die Konsole via <code>getline(std::cin, str)</code> eingelesen, nun will ich aber endlich eine Datei normal öffnen. Zunächst einmal eine (zwar syntaktisch korrekte, aber semantisch falsche - ich weiß es!) Datei, die ich nun einlesen will:</p>
<pre><code class="language-cpp">// test source file
namespace NS1 {
    namespace NS2 {
        /* template definition on namespace because i take only care of
           syntactic errors ;) */
        template&lt;typename T&gt;
        namespace {
        }
    }
}
</code></pre>
<p>Nun will ich wissen, wie ich die Datei am besten einlesen soll und wie ich zum Einen die Newlines behandeln soll**[1]**, zum Anderen welche RegEx-Bibliothek ich nutzen soll um die Kommentare beim Preprocessing zu strippen und ob das klappen wird.</p>
<p>Zum letzten Punkt: Da, in der aktuellen Version, meine Regeln komisch definiert sind und mir bei einem Fehler über <code>parse_info&lt;&gt;.stop</code> einfach das ganze Source ausgeben wird (als ich es via Konsole eingelesen habe) bin ich am Überlegen, wie das dann bei dem File aussehen würde <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Vielen Dank für eure Unterstützung,<br />
Christian</p>
<p><em>Fußnoten:</em><br />
<strong>[1]</strong> Ich habe beim Parsen folgenden Code genutzt, um einige unnötige Whitespaces vom Scanner ignorieren zu lassen, damit ich diese nicht selber in die Regeln schreiben muss (wobei str der eingegebene Code ist und fpp_grammar in meinem vorherigen Post in einer kleineren/abgespeckteren Version definiert ist):</p>
<pre><code class="language-cpp">fpp::compiler::spirit::fpp_grammar g;
parse_info&lt;&gt; info = parse(str.c_str(), g, space_p);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2000257</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2000257</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 30 Dec 2010 09:29:11 GMT</pubDate></item></channel></rss>