मैं QI और फीनिक्स का उपयोग कर रहा है, और मैं एक छोटे से व्याकरण है कि 4 bools जो एक समारोह कॉल एक अर्थ कार्रवाई के अंदर के लिए तर्क के रूप में इस्तेमाल किया जा रहे हैं देता है लिखना चाहते हैं।बूस्ट :: आत्मा :: क्यूई। इनलाइन पर्सर एक्सप्रेशन को स्टैंडअलोन व्याकरण में कैसे बदलें, और उनके द्वारा उत्पन्न टुपल को कैसे अनपैक करें?
मैं कई कार्य है कि उन चीजों की जरूरत है, और अब तक मैं इस दृष्टिकोण का इस्तेमाल किया है:
(qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
[px::bind(&Bool4Function, spirit::_val, spirit::_1, spirit::_2, spirit::_3, spirit::_4)]
और यह अपने आप पर ठीक है सिर्फ सादा बदसूरत और भ्रामक है, जबकि, जगह यह सब का उपयोग कर, नामस्थान भागों का उपयोग करके भी।
इसलिए मैं एक स्टैंडअलोन व्याकरण में इस अभिव्यक्ति को निकालने के लिए चाहता था।
तो मैं इस कोशिश की (क्रेडिट testbed के लिए ildjarn को जाता है):
///// grammar implementation /////
#include <boost/fusion/include/vector10.hpp>
#include <boost/spirit/include/qi_bool.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <boost/spirit/include/qi_rule.hpp>
#include <boost/spirit/include/qi_string.hpp>
struct FourBools : boost::spirit::qi::grammar<
char const*,
boost::fusion::vector4<bool, bool, bool, bool>()
>
{
typedef boost::fusion::vector4<bool, bool, bool, bool> attribute_type;
FourBools() : base_type(start_)
{
using boost::spirit::bool_;
start_
= "4bools:"
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ','
>> bool_ >> ';'
;
}
private:
boost::spirit::qi::rule<
base_type::iterator_type,
base_type::sig_type
> start_;
};
FourBools const fourBools;
///// demonstration of use /////
#include <string>
#include <ios>
#include <iostream>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_parse.hpp>
void noDice(bool a, bool b, bool c, bool d)
{
}
void worksFine(boost::fusion::vector4<bool, bool, bool, bool> a)
{
}
int main()
{
namespace phx = boost::phoenix;
namespace spirit = boost::spirit;
std::string const input("4bools:true,true,true,false;");
char const* first = input.c_str();
char const* const last = first + input.size();
bool const success = spirit::qi::parse(
first, last,
fourBools[phx::bind(&noDice, spirit::_1)]
);
if (!success)
std::cout << "parse() failed\n";
else if (first != last)
std::cout << "didn't consume all input\n";
std::cout.flush();
}
कि जब तक fourBools[phx::bind(&noDice, spirit::_1)]
संकलन नहीं है fourBools[phx::bind(&worksFine, spirit::_1)]
साथ बदल दिया है।
इसका मतलब है, मेरी समस्या फ़ंक्शन के हस्ताक्षर से मेल खाने के लिए तर्कों का अनपॅकिंग है, क्योंकि तर्कों की संख्या हस्ताक्षर स्तर (चार बूलों का एक टुपल, स्वयं चार बूल बनाम) पर भिन्न होती है।
यह सीधे फोनिक्स प्लेसहोल्डर का उपयोग कर, रैपर जो अपने मौजूदा कार्यों कि जरूरत है उन्हें अलग करने के लिए अलग-अलग तर्क में tuples का अनुवाद लेखन के बजाय खोल करना संभव है? यदि यह है, तो इसके लिए वाक्यविन्यास क्या होगा? सब के बाद, (qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
की तरह एक इनलाइन संस्करण ठीक काम करता है जब spirit::_1 - spirit::_4,
प्लेसहोल्डर द्वारा 'अनपैक किया'।
यह इस संस्करण के साथ-साथ एक टपल वापस लौट आता है के रूप में मेरे लिए दिखाई देता है, और किसी भी तरह एक व्याकरण है कि एक रिटर्न के विपरीत ऊपर दृष्टिकोण के साथ unpackable है, यही कारण है कि।
मैं इससे कैसे निपटूं?
इस तरह की टिप्पणियां शायद इस पर फंसे हुए हैं, लेकिन मुझे बस अपनी छाती से इस तरह के कोड को देखने के बारे में मेरी इच्छा है। मैं इसके बगल में बहुत गड़बड़ महसूस करता हूं, यह बहुत प्रेरणादायक है, सूचीबद्ध चीजों में से आधे को भी नहीं पता था और मैंने सोचा कि मैं पहले से ही बेहतर हो रहा हूं। वैसे भी, मैं कल एक रिपो शामिल करूंगा, अगर यह अभी भी आपकी पोस्ट का विश्लेषण करने के बाद काम नहीं करेगा। – Erius
@ एरियस: -] यदि आप एक रेपो पोस्ट करना समाप्त करते हैं, तो कृपया इस उत्तर पर एक टिप्पणी पोस्ट करें, इसलिए मुझे अपने एसओ इनबॉक्स में एक संदेश मिलेगा, अन्यथा शायद मैं आपका संपादन नहीं देखूंगा। – ildjarn
हो गया, फिर से धन्यवाद। – Erius