If I generate a parser using FSYacc will it be thread safe?
The only reason I ask is because the functions
Parsing.rhs_start_pos
and Parsing.symbol_end_pos
don't appear to have any state passed into them, which would lead me to assume that they are getting the current NonTerminal/Symbols from a shared location, is this correct?
After reflecting the code I see that they are getting the postion from a static property
internal static IParseState parse_information
{
get
{
return parse_information;
}
set
{
parse_information = value;
}
}
Is this correct? If so what can I do about it?
Edit: I also see a static method called set_parse_state
public static void set_parse_state(IParseState x)
{
parse_information = x;
}
But that still wont solve my problem...
I really don't like to answer my own question, however since this could save someone else a world of grief someday I will.
It turns out that the functions provided in the parsing module are NOT thread safe.
What you can do however is access the parseState
"variable", which is of type IParseState
, in your nonterminal action.
For example (rough but work with me): If you have a NonTerminal like
%token<string> NAME %% Person: NAME NAME { $1 (* action *) }
The code that gets generated is:
(fun (parseState : Microsoft.FSharp.Text.Parsing.IParseState) -> let _1 = (let data = parseState.GetInput(1) in (Microsoft.FSharp.Core.Operators.unbox data : string) ) in Microsoft.FSharp.Core.Operators.box((_1) : 'Person) );
So you can interact with that parseState object in the same fashion.
%token<string> NAME %% Person: NAME NAME { parseState.DoStuff(); }
The rhs_start_pos
method basically does this:
let startPos,endPos = parseState.InputRange(n)
and the symbol_end_pos
does this:
let startSymb,endSymb = parseState.ResultRange
I hope this helps