【问题标题】:Context sensitive data processing in F#F# 中的上下文敏感数据处理
【发布时间】:2010-09-15 18:11:15
【问题描述】:

我最近完成了一个生成字符串列表的项目,我想知道最好的方法。

字符串生成是上下文相关的,以确定它是否可以接受(它是游戏中的一系列游戏,所以你必须知道最后一次游戏是什么)

我这样做的方式是使用传递上下文参数和术语的函数,如果可以接受,则递归继续,如果不是,则终止(因为不能接受进一步的字符串。)函数还收到一个“长度”参数以确保它最终终止

基本上这是生成一种语言(一定长度)接受的每个可能的字符串。

现在,我让这个工作,甚至相当好和干净,但我想知道是否有更好的方法来做到这一点。具体来说,“状态机” monad 在生成上下文相关语法方面是否能很好地工作?或至少类似的东西?想要启动像 parsec 这样的问题似乎很简单,还有其他结构可以有效地操纵语言吗?

任何想法都将不胜感激。

【问题讨论】:

  • 您可以发布您创建的任何代码吗?更容易理解你的意思。

标签: f# grammar monads


【解决方案1】:

我觉得这个问题看起来很有趣,所以我尝试了几种不同的方法来实现它。下面的代码是最有希望的方法。我认为它解决了所描述的问题,尽管我不确定一些细节。

基本上它允许一种形式的上下文敏感语法,但只有一种非常简单的形式,其中每个产生式只能依赖于前一个符号。下面的代码构建了一些组合器,允许将产品直接编码为“生成器”,并处理场景背后的长度限制。

type sym = Xa | Xb | Xc          // The terminal symbols 
type word = sym list             // A string of terminals

type gen = int -> sym list seq   // Generate words up to the given length

/// Passes the previous symbol to a generator, after checking the length.
let (+>) : sym  -> (sym -> gen) -> gen = 
    fun x g l -> if l<=0 then Seq.empty 
                         else seq { for xs in g x (l-1) -> x :: xs }

let nil _ = seq { yield [] }                    // Generate just the empty word            
let (|||) xs ys l = Seq.append (xs l) (ys l)    // Union of two generators
let notAccepted _ = Seq.empty                   // Don't generate anything

let tryAll g = Xa +> g ||| Xb +> g ||| Xc +> g  // Run g starting with any sym

// Generators for non-terminals.  Each takes the previous symbol as an argument,
// and generates a (possibly empty) sequence of lists of symbols.
let rec gR = function Xa ->  Xb +> gS ||| Xc +> gR  ||| nil  
                    | Xc ->  Xb +> gS                        | _ -> notAccepted
    and gS = function Xb ->  Xa +> gR                        | _ -> notAccepted


let genTop = tryAll gR  // The top level generator begins with gR with any sym

let words = genTop 4    // Generate words up to length 4
// val words : seq<sym list> 
//           = seq [[Xa; Xb; Xa]; [Xa; Xc; Xb; Xa]; [Xa]; [Xc; Xb; Xa]]

【讨论】:

  • 非常有趣的答案......我不知道我在做什么,我最初发布了这个,但我随后进入了一个类似象棋的游戏,这将有助于......谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2014-01-12
相关资源
最近更新 更多