Jump to content
  • Advertisement
Sign in to follow this  
Marmis

spirit and phoenix - passing variables

This topic is 4205 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Please, consider the following snippet:
// Main function
int main()
{
    const std::string input = "[foofoo]\nvar=val";

    test_grammar g;
    std::string output;
    
    // std::string variable;
    // int value;

    std::cout << parse(input.c_str(), g[var(output) = arg1]).full << std::endl // 1
    std::cout << output << std::endl; // foofoo
    
    std::cin.get();
    return 0;
}

// The rather simple grammar I'm using
struct test_closure : closure<test_closure, std::string, std::string, int>
{
    member1 name;
    member2 var;
    member3 val;
};

struct test_grammar : public grammar<test_grammar, test_closure::context_t>
{
    template <typename ScannerT>
    struct definition
    {
        definition(const test_grammar& self)
        {  
           section_title = confix_p(ch_p('['), (*anychar_p)[self.name = construct_<std::string>(arg1, arg2)], ch_p(']'));
           
           item = confix_p(*anychar_p, ch_p('='), *anychar_p);

           section = (section_title >> list_p(item));
        }
        
        rule<ScannerT> section_title, section, item;

        const rule<ScannerT>& start() const { return section; }
    };
};

Seems to be working fine, but is it possible to pass variable and value in the same way as I passed output? If it is, how? g[var(output) = arg1, ...] ? Am I just somehow missing the syntax or am I doing it the "wrong way"?

Share this post


Link to post
Share on other sites
Advertisement
I don't know off-hand; but a good place to look for answers begins here:

https://lists.sourceforge.net/lists/listinfo/spirit-general

The mailing list is very active, and I'm sure you'd get a fairly quick answer, if nothing happens in this thread.

Share this post


Link to post
Share on other sites
*bump, still struggling with this one. I'm pretty confident this is somehow possible. Any help will be appreciated, thanks!

Share this post


Link to post
Share on other sites
What, exactly, are you trying to do? If it's what I think it is, this example might help. The key is the closure type, which allows you to carry information through an entire syntax tree. I clipped this code out of a parser I wrote to build an abstract syntax tree for a special purpose language and simplified it some.

#include <boost/spirit.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#include <boost/spirit/phoenix/functions.hpp>

struct closure : boost::spirit::closure<closure, int, int>
{
member1 _result;
member2 _second;
};

rule<boost::spirit::scanner<>, closure::context_t> add;

//matches [int:int]
add =
(
ch_p('[') >>
int_matcher[add._result = arg1] >> //Notice how we can refer to add.
//arg1 is the result of int_matcher. (I made the name int_matcher up.)
//arg1 is always the name of the result when you nest rules.
//It also will refer to the member1 _result member
//of your custom rule's closure.
ch_p(':') >>
int_matcher[add._second = arg1] >>
ch_p(']')
)
[add._result = add._result + add._second];

//To actually parse...
int result;
if (parse("[10:5]", (add[ assign_a(result) ])).full )
{
assert(result == 15);
}




Spirit gets real ugly real quick.
You have been warned.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!