Re: parser compiled with msvc9 is four to five times slower relative to msvc8
Carl Barron <cbarron413 <at> roadrunner.com>
2008-11-06 01:51:29 GMT
On Nov 5, 2008, at 5:10 PM, Michael Weber wrote:
> Hello,
> [smp msvc stuff , don't use it:)]
> 3. Is there an example of how to generate parse trees tagged with
> rule IDs in Spirit 2, with tree nodes containing begin / end
> iterators to matched ranges in the input string?.
>
> Scanning the mailing list, I am hopeful that Spirit 2 will be the
> way to go for the future. However, the documentation / examples are
> still a little sparse. My current CSS parser generates a parse tree
> where each node is tagged with a rule ID and iterators into the
> input buffer. The Spirit 2 documentation for these topics looks like
> placeholders for unwritten content (unless I am missing files). I
> also cannot find an demonstrating how to generate an equivalent
> parse tree with Spirit 2, but perhaps I do not understand the
> examples.
>
There are no built in trees or rule ids in spirit 2. You have
complete control of what a parser creates as a 'return' There are no
closures
only local variables, inherited_variables , It makes writing grammars
and their action actually much simpler and execute much faster as
welll. That said the purpose of rule-ids was to identifiy what type
of node you have, so a separate type for each different node type
serves
the purpose.
Examplle a simple four function calculator of doubles requires five
different nodes 4 of which are essetially the same and one
holds a double so
template <char C> struct binary_node;
typedef boost ::variant
<
double,
boost::recursive_wrapper<binary_node<'+'> >,
boost::recursive_wrapper<binary_node<;'-'> >,
boost::recursive_wrapper<binary_node<'*'> >,
boost::recursive_wrapper<binary_node<'/'> >
> expr_node;
template <char C> struct make_op;
template <> struct make_op<'+'> {typedef std::plus<double> type;};
template <> struct make_op<'-'> { typedef std::minus<double> type;};
etc.
template <char C>
struct binary_node
{
expr_node left,right;
binary_node(const expr_node &a,const expr_node &b)
:left(a),right(b);
};
defines an ast for a an expression. evaluation is simply a functor
with overloaded operator ()'s.
struct evaluate:boost::static_visiitor<double>
{
double operator () (double x) const { return x;}
template <char C>o operator () ( const binary_node<C> & x) const
{
typename make_op<C>::type operation;
return operation( evaluate(left), evaluate(right));
}
};
now the grammar is simply
expr_node & operator += ( expr_node &left ,const expr_node &left)
{
return left = binary_node<'+'>(left,right);
}
// etc for op -= ,*=,/=
template <class Iter>
struct expression_gram:grammar
<
Iter, // the iterator
expr_node(), // signature synthetic attribute node and no
inherited_attributes,
space_type // skipper type
>
{
expression_gram():expr_gram::base_type(expr) // expr is the start rule
{
expr = term [_val = _1]
>> *( '+' >> term [ _val += _1]
| '-' >> term [ _val -= _1]
)
;
term = factor [_val = _1]
>> *( '*' >> factor [_val *= _1]
| '/' >> factor [_val /= _1]
)
;
factor = doiuble_ [[_val = _1]
| '(' expr [_val = _1] >> ')'
;
}
typedef rule<Iter,expr_node(),space_type> rule_t;
rule_t expr,term,factor;
};
generates the tree
int main()
{
std::string data("1 + 2");
typedef std::string::iterator iterator;
iterator first(data.begin();
expression_grammar<iterator> gram;
expr_node tree;
bool r = phrase_parse(first,data.end(),gram,tree,space);
if(r)
{
std::cout << "result is " << apply_visitor(evalujate(),tree) << '\n';
}
else
{
std::cout << "Parse failed\n";
}
}
notice how much cleaner this is!!
I hope this fills in some 'spaces' left by the docs. The same
approach can probably be used for CSS allthough the actual types
are different and the grammar is different. There are other changes
in grammars from spirit 1 like names of primittives,,,
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/