सवाल नीचे की ओर बोल्ड है, समस्या को अंत तक आसवन कोड के टुकड़े द्वारा संक्षेपित किया गया है।
मैं अपने कंपोनेंट सिस्टम को टाइप करने की कोशिश कर रहा हूं (टाइप सिस्टम से टाइप करने के लिए स्ट्रिंग से) सिंगल कंपोनेंट में (जैसा कि लक्की द्वारा परिभाषित किया गया है)। मैं उपयोग कर रहा हूँ boost::array
, boost::variant
और boost::mpl
, क्रम में इस लक्ष्य को हासिल करने के लिए। मैं चाहता हूं कि एक प्रकार में एकीकृत मेरे प्रकार के लिए पार्सर और जनरेटर नियम हों। एक अपरिभाषित प्रकार है, एक int4 (नीचे देखें) प्रकार और एक int8 प्रकार। संस्करण के रूप में पढ़ता है variant<undefined, int4,int8>
।
int4 लक्षण:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
template<>
struct rbl_type_parser_rule<rbl_int4>
{
typedef rbl_int4_parser_rule_definition string_parser;
};
उपरोक्त संस्करण अपरिभाषित के रूप में बाहर शुरू होता है, और फिर मैं नियमों को आरंभ करता हूं। मुझे एक समस्या थी, जिसके कारण 50 पृष्ठों की त्रुटियां हुईं, और मैं अंत में इसे नीचे ट्रैक करने में कामयाब रहा, वेरिएंट का उपयोग करता हैoperator=
हुईं असाइनमेंट के दौरान और किसी boost::spirit::qi::int_parser<>
अन्य (ऑपरेटर =) को नहीं सौंपा जा सकता है।
इसके विपरीत, मुझे अपने अपरिभाषित प्रकार से कोई समस्या नहीं है:
struct rbl_undefined_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type;
rule_type rule;
rbl_undefined_parser_rule_definition()
{
rule.name("undefined parse rule");
rule = boost::spirit::qi::eps;
}
};
template<>
struct rbl_type_parser_rule<rbl_undefined>
{
typedef rbl_undefined_parser_rule_definition string_parser;
};
समस्या का आसवन:
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>
typedef boost::spirit::qi::rule<std::string::iterator,void()> r1;
typedef boost::spirit::qi::rule<std::string::iterator,int()> r2;
typedef boost::variant<r1,r2> v;
int main()
{
/*
problematic
boost::spirit::qi::int_parser<int32_t> t2;
boost::spirit::qi::int_parser<int32_t> t1;
t1 = t2;
*/
//unproblematic
r1 r1_;
r2 r2_;
r1_ = r2_;
v v_;
// THIS is what I need to do.
v_ = r2();
}
कंक्रीट पार्सर और नियमों के बीच एक अर्थपूर्ण अंतर है। मेरा मस्तिष्क इस समय धूम्रपान कर रहा है, इसलिए मैं व्यावहारिकता के बारे में सोचने वाला नहीं हूं, मेरा सवाल यह है कि मैं इस समस्या को कैसे हल करूं? मैं समस्या को हल करने के लिए तीन तरीकों के बारे में सोच सकता हूं।
एक: स्टेटिक फ़ंक्शन सदस्य:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
//boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
static boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
मुझे लगता है कि दृष्टिकोण एक सुरक्षित कोड को रोकता है? ?
दो: इंटीग्रल पार्सर एक शेयर्ड_प्ट्र में लपेटा जाता है। टाइपिंग सिस्टम के लिए टीएमपी के साथ परेशान होने के दो कारण हैं: 1 दक्षता, 2 केंद्रीयकरण संबंधी चिंताएं घटकों में। पॉइंटर्स का उपयोग करना पहला कारण है।
तीन: ऑपरेटर = को नो-ऑप के रूप में परिभाषित किया गया है। वेरिएंट गारंटी देता है कि lhs
असाइनमेंट से पहले डिफ़ॉल्ट रूप से निर्मित है।
संपादित करें: मैं सोच रहा हूं विकल्प 3 सबसे अधिक समझ में आता है (ऑपरेटर = एक नो-ऑप है)। एक बार नियम कंटेनर बन जाने के बाद यह नहीं बदलेगा, और मैं केवल एक प्रकार के नियम विशेषता को इसकी भरपाई करने के लिए बाध्य करने का काम कर रहा हूं।
parser_int32_t
राज्य है और एक संदर्भ लिया गया है। यदि स्टेटलेस है या कॉपी बनाई गई है, तो यह सुरक्षित है। शब्दार्थ से, मैं कहूंगा कि एक प्रति बनाई गई है।