我可以将参数传递给我的fsyacc解析器吗?

时间:2012-09-19 12:27:17

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

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

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在每个非终端中访问它,我可以在那里存储参数,还是一个坏主意?

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

修改

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

%token <string * IScope> IDENT

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

1 个答案:

答案 0 :(得分:0)

Dictionary<string, obj>中有LexBuffer,也可以通过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

由于还没有任何答案,我现在接受这个答案。 尽管建议一个更好的解决方案,然后我会改变接受的答案。