【问题标题】:Can I pass parameters to my fsyacc parser?我可以将参数传递给我的 fsyacc 解析器吗?
【发布时间】:2012-09-19 12:27:17
【问题描述】:

我知道可以将参数传递给词法分析器:

rule tokenize scope = parse
  | whitespace       { tokenize scope lexbuf                       }
  | newline          { newline lexbuf; tokenize scope lexbuf       }

但我无法以类似的方式定义解析器开始符号。

我试图这样定义它:(感谢this问题)

%type < (IScope, AST.Script) Fun > Script

// with the following definition in the head section of the parser:
type ('a,'b) Fun = 'a -> 'b

但是我必须像这样定义每个非终结符,它们都会返回 lambdas。不过,这不是我想要实现的,我希望能够在几个非终端中访问 scope 参数并在解析期间执行它们的操作。

我注意到IParseState 类型中有一个ParserLocalStore,它只包含LexBuffer(仅通过调试检查)。由于我可以在每个非终端中通过parseState 访问它,我是否可以在其中存储参数,或者这是一个坏主意?

我曾考虑在解析器的头部使用可变变量,但它们将是静态的(我认为?),这会阻止我同时解析多个输入......

编辑:

目前我将scope 参数存储在特定令牌中:

%token <string * IScope> IDENT

我将scope 传递给 Lexer,后者在创建它们时将其嵌入到相关标记中......我真的不喜欢这个解决方案,但我无法想出更好的东西。

【问题讨论】:

  • 不是答案,但您考虑过 FParsec 吗?参数传递非常简单。
  • 暂时没有。我们有另一个解析器项目即将推出,可能会在那里使用 ANTLR。如果我们(在某个时候)决定在当前项目中也使用 ANTLR,我可以更轻松地使用 fsyacc 进行移植。使用解析器组合器(至少据我所知)我没有非常清晰的语法,并且必须以完全不同的方式做所有事情,而 fsyacc / ANTLR 解析器的大部分结构似乎都是相似的。

标签: parsing f# fsyacc fslex f#-powerpack


【解决方案1】:

LexBuffer中有一个Dictionary&lt;string, obj&gt;,也可以通过parseState获取。没有找到更好的解决方案,我最终将我的参数存储在那里。

我知道这很可能不打算以这种方式使用,并且可能在 fsyacc 的未来版本中不可用,但我现在坚持使用它。如果有人需要做同样的事情,我会在此处留下我创建的两个扩展方法,以便以更简洁的方式访问我的参数:

type IParseState with
    member x.LexBuffer() = x.ParserLocalStore.["LexBuffer"] :?> LexBuffer<char>

type LexBuffer<'a> with
    member x.SomeParameter
        with get() = x.BufferLocalStore.["SomeParameter"] :?> SomeParamType
        and set(v) = x.BufferLocalStore.["SomeParameter"] <- v

由于还没有任何答案,我暂时接受这个。 请随意提出更好的解决方案,我会更改已接受的答案。

【讨论】:

    猜你喜欢
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 2011-02-20
    相关资源
    最近更新 更多