2009-06-04 6 views
3

Si je génère un analyseur en utilisant FSYacc sera-t-il thread-safe?Les analyseurs syntaxiques générés par le thread FSYacc sont-ils sûrs?

La seule raison pour laquelle je demande est parce que les fonctions

Parsing.rhs_start_pos et Parsing.symbol_end_pos

se font pas semblent d'avoir un Etat passé en eux, ce qui me conduirait à supposer qu'ils obtiennent le courant NonTerminal/Symboles d'un emplacement partagé, est-ce correct?

Après avoir réfléchi le code que je vois qu'ils obtiennent la postion d'une propriété statique

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

Est-ce exact? Si oui, que puis-je faire à ce sujet?

Edit: Je vois aussi une méthode statique appelée set_parse_state

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

Mais cela marche toujours l'habitude de mon problème ...

Répondre

2

Je n'aime vraiment pas répondre à ma propre question, mais depuis cette pourrait sauver quelqu'un d'autre un monde de chagrin un jour je le ferai.

Il s'avère que les fonctions fournies dans le module d'analyse ne sont PAS thread-safe. Vous pouvez cependant accéder à la variable "parseState", de type IParseState, dans votre action non-terminale.

Par exemple (rude, mais travailler avec moi): Si vous avez un non-terminal comme

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

Le code qui est généré est:

 
(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) 
); 

Ainsi, vous pouvez interagir avec cet objet parseState de la même manière.

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

La méthode rhs_start_pos fait essentiellement ceci:

 
let startPos,endPos = parseState.InputRange(n) 

et symbol_end_pos ce que cela:

 
let startSymb,endSymb = parseState.ResultRange 

J'espère que cette aide

Questions connexes