2009-06-04 3 views
3

Wenn ich einen Parser mit FSYacc erzeuge, wird es threadsicher sein?Sind Parser von FSYacc thread sicher?

Der einzige Grund, warum ich frage ist, weil die Funktionen

Parsing.rhs_start_pos und Parsing.symbol_end_pos

nicht erscheinen jeder Staat in sie bestanden zu haben, die mich führen würde davon ausgehen, dass sie den Strom bekommen NonTerminal/Symbole von einem freigegebenen Speicherort, ist das korrekt?

Nach dem Code reflektiert ich sehe, dass sie die Postion von einer statischen Eigenschaft

internal static IParseState parse_information 
{ 
    get 
    { 
     return parse_information; 
    } 
    set 
    { 
     parse_information = value; 
    } 
} 

Ist bekommen das richtig? Wenn ja, was kann ich dagegen tun?

Edit: Ich sehe auch eine statische Methode set_parse_state

public static void set_parse_state(IParseState x) 
{ 
    parse_information = x; 
} 

Aber das noch pflegt mein Problem lösen ...

Antwort

2

ich da dies aber wirklich nicht, wie genannt, meine eigene Frage zu beantworten könnte jemand anderes eine Welt der Trauer eines Tages retten.

Es stellt sich heraus, dass die Funktionen im Parsing-Modul NICHT Thread-sicher sind. Was Sie jedoch tun können, ist die parseState "Variable", die vom Typ IParseState ist, in Ihrer Nicht-Terminal-Aktion.

Zum Beispiel (rau, aber mit mir arbeiten): Wenn Sie ein Nicht-End haben wie

 
%token<string> NAME 
%% 
Person: 
     NAME NAME { $1 (* action *) } 

Der Code, der generiert wird ist:

 
(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 kann man mit diesem parseState Objekt interagieren auf die selbe Art.

 
%token<string> NAME 
%% 
Person: 
     NAME NAME { parseState.DoStuff(); } 

Die rhs_start_pos Methode funktioniert im Grunde diese:

 
let startPos,endPos = parseState.InputRange(n) 

und die symbol_end_pos tut dies:

 
let startSymb,endSymb = parseState.ResultRange 

Ich hoffe, das hilft