Boost logo

Boost :

From: Joel de Guzman (joel_at_[hidden])
Date: 2008-07-28 22:33:39


Robert Ramey wrote:

> My general conception is that parsing can be consider
> as various quasi - independent phases.
>
> a) specification of grammar - source code preparation
> b) compiliation
> c) instantiontion/construction of grammar definition
> d) usage of c) to parse a text string
> e) destruction of instance.
>
>>From this I want to conclude that phase d) does not change
> the grammar definition so so that in a multi-threading
> environment, the invocation of the scoped_lock
> would be limited to phases c) and e).
>
> That is, I want to believe that the following example adapted
> from the spirit documentation would work:
>
> const my_grammar g; // note addition of const
>
> if (parse(first, last, g, space_p).full)
> cout << "parsing succeeded\n";
> else
> cout << "parsing failed\n";
>
> The reason I ask is that the serialization library uses
> spirit to parse xml archives. Recently, I made changes
> to make the library thread-safe. I did this without using
> mutexes/locks by confine all non-const operations to
> construction and destruction and using static object
> constructed/destructed at pre-main and post main
> time time. Although the jury is still out on this, I believe
> it will make the serialization library thread safe without
> the need for using threading primitives and libraries.

Alas, it's not as simple as that. The grammar itself is thread-safe.
It's the instantiation of the grammar::definition that is not, and
requires BOOST_SPIRIT_THREADSAFE, and hence, reliance on Boost.Threads.

(FWIW, Spirit-2 solves the thread-safety problems and does away with
Threads. I won't expect you to switch to Spirit2 any time soon though.)

A potential solution is to "prime" the grammar at pre-main. There's
no direct way to do it ATM, but you can do a dummy parse to achieve
the effect (e.g. have a static object that does that in its constructor).
Another potential solution (one that Spirit2 does) is to instantiate
the grammar::definition directly in the stack and call its "start"
rule directly.

Also, if you do it this way, don't use closures (I recall you are
using ASTs, right?). Spirit-1 has problems with thread-safety in
2 areas: grammar-definitions and closures.

Regards,

-- 
Joel de Guzman
http://www.boostpro.com
http://spirit.sf.net

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk