Jump to content
  • Advertisement
Sign in to follow this  
Verg

[SOLVED] - boost::spirit parser that returns a type (closures ROCK)

This topic is 4815 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

It seems spirit's built-in parsers can return values... parsers such as "real_p" return real numbers that you can access through actors (like assign_a) or through boost::phoenix arguments (phoenix::arg1, etc)... I've tried to create a parser that returns a reference to an object, instead of the directly matched value. object_p would return a "RefType" reference, though it uses a uint_parser<> to parse out a pointer. In other words, inside a class I derived from "uint_parser", I tried to decorate the return value of "uint_parser" by casting the value to a pointer, and then referencing it: *((RefType *)uint_parser_return_val) This doesn't work because internally, spirit checks the result of the parser against the scan type... and so the code fails to compile... If the RefType is "long"... but the uint_parser parses out "unsigned ints"... internally, the parser won't score a match--- but worse, it fails to compile because the result of the "scan" isn't the same as the parser's return type. ..... Anywho... long story short... Has anyone been able to create a parser that may parse out a value, but that returns a different type? I could just use an actor that casts the pointer to an object of the reference type, but recursive-descent parsing becomes nearly impossibly cumbersome when doing that (temporary variables to hold the parsed out values can't be used recursively) Thanks for any thoughts. Chad [Edited by - Verg on September 8, 2005 10:59:21 PM]

Share this post


Link to post
Share on other sites
Advertisement
I'm not entirely sure what you're asking. Can you show a BNF for what you're trying to do with a the type of each item in the grammar?

Share this post


Link to post
Share on other sites
Thanks anyway, SiCrane... the problem has been solved...

Had I known just how cool "closures" were, I wouldn't have had to ask you [grin]

Here's the code, for future reference... the difficulty I had was in understanding that [rulename.val = phoenix::arg1] would actually take the previous rule's closure for "phoenix::arg1"... I thought it would evaluate to the parsed string, or something.


template<typename ValueType, bool numeric = true>
class GetAttribute{

public:

struct calc_closure : boost::spirit::closure<calc_closure, ValueType>
{
member1 val;
};

void getAttribute(SurfaceDesc &desc, ValueType &variable,
const char *attr_name)
{
ValueType temp;
__int64 ptrvar = 0;

_ptr_parser = '[' >> _hexparser[assign_a(ptrvar)]
[assign_ptr_a(temp,ptrvar)]
[_ptr_parser.val = phoenix::var(temp)]
>> ']';

_factor = _ptr_parser[_factor.val = phoenix::arg1] |
real_p[_factor.val = phoenix::arg1];

_term = _factor[_term.val = phoenix::arg1] >>
*(('*' >> _factor[_term.val *= phoenix::arg1]) |
('/' >> _factor[_term.val /= phoenix::arg1]));

_expression = _term[_expression.val = phoenix::arg1] >>
*(('+' >> _term[_expression.val += phoenix::arg1]) |
('-' >> _term[_expression.val -= phoenix::arg1]));

const char *string = desc.attributeString(attr_name);

if(string)
{
if(parse(string,
_expression[phoenix::var(variable) = phoenix::arg1],
space_p).full)
{
// successful parse
}
}
}

private:

// the rule types include "calc_closure::context_t" in the
// template parameters
};


That code will take a string like this:

[002879ab]/2 + (3 * [002878b0]/4)

And convert the bracketed numbers (pointers) to the numerical variables they
represent

100/2 + (3 * 1000/4)

I was unaware that you could define a rule like this one:


_ptr_parser = '[' >> _hexparser[assign_a(ptrvar)]
[assign_ptr_a(temp,ptrvar)]
[_ptr_parser.val = phoenix::var(temp)]
>> ']';


and then the following would be evaluated correctly:


_factor = _ptr_parser[_factor.val = phoenix::arg1] |
real_p[_factor.val = phoenix::arg1];


I didn't realize that "phoenix::arg1" had picked up "_ptr_parser's" closure
in that expression. That RULES.

Apparently, closures rock [grin]



Chad

Share this post


Link to post
Share on other sites
Quote:
Original post by Verg
Apparently, closures rock [grin]


spirit closures simulate dynamic scoping in C++! thats why you probably got confused.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!