2012-09-19 122 views
3

我知道这是可能的参数传递到词法分析器:我可以将参数传递给我的fsyacc分析器吗?

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 

但后来我不得不这样定义每一个非终端符号和他们都回lambda表达式。这不是我想要虽然实现的,我希望能够几个非终端中访问scope参数和分析过程中执行他们的行动。

我注意到IParseState类型中有ParserLocalStore类型,其中只包含LexBuffer(只能通过调试进行检查)。由于我在每一个非终端通过parseState访问它,我也许能在那里储存参数,或者说是一个坏主意?

我想到了在解析器头部分采用可变的变量,但他们是静态的(我想?),而且会阻止我同时分析多个输入...

编辑:

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

%token <string * IScope> IDENT 

我通过scope的词法,谁其嵌入相关令牌w ^如果他创造了它们......我真的不喜欢这个解决方案,但是我还是无法想出更好的东西。

+0

不是一个答案,但你有没有考虑FParsec?参数传递很容易。 – Daniel

+0

目前不在。我们有另一个解析器项目,可能会在那里使用ANTLR。如果我们(在某个时候)也决定使用ANTLR来处理当前的项目,那么我可以更轻松地使用fsyacc进行移植。随着解析器组合(据我所知至少)我没有一个很清晰的语法和所要做的一切相当不同,而大部分一fsyacc/ANTLR解析器的结构似乎是相似的。 – enzi

回答

0

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

由于没有得到任何答案,但我会接受这个一个现在。 随意但提出一个更好的解决方案,我会改变接受的答案。

相关问题