FSYacc 生成的解析器线程安全吗?

发布于 2024-07-23 07:34:40 字数 633 浏览 5 评论 0原文

如果我使用 FSYacc 生成解析器,它是线程安全的吗?

我问的唯一原因是因为函数

Parsing.rhs_start_posParsing.symbol_end_pos

似乎没有任何状态传递给它们,这会让我假设他们从共享位置获取当前的非终端/符号,这是正确的吗?

反映代码后,我看到他们从静态属性获取位置,

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

这是正确的吗? 如果是这样我该怎么办?

编辑:我还看到一个名为 set_parse_state 的静态方法,

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

但这仍然无法解决我的问题......

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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

偏闹i 2024-07-30 07:34:40

我真的不想回答我自己的问题,但是,因为这可以让别人免于悲伤,有一天我会的。

事实证明,解析模块中提供的函数不是线程安全的。
但是,您可以做的是在非终结符操作中访问 parseState “变量”,它的类型为 IParseState

例如(粗糙但和我一起工作):
如果您有一个像这样的非终端,则

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

生成的代码是:

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

因此您可以以相同的方式与该 parseState 对象进行交互。

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

rhs_start_pos 方法基本上执行此操作:

let startPos,endPos = parseState.InputRange(n)

symbol_end_pos 执行此操作:

let startSymb,endSymb = parseState.ResultRange

我希望这会有所帮助

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文