Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# F中的上下文敏感数据处理#_F#_Grammar_Monads - Fatal编程技术网

F# F中的上下文敏感数据处理#

F# F中的上下文敏感数据处理#,f#,grammar,monads,F#,Grammar,Monads,我最近完成了一个项目,其中我正在生成字符串列表,我想知道最好的方法是什么 字符串生成是上下文敏感的,以确定是否可以接受(这是游戏中的一系列游戏,因此您必须知道最后一个游戏是什么) 我这样做的方式是使用一个传递了上下文参数和术语的函数,如果它是可接受的,它将递归地继续,如果它不是终止的(因为不能接受更多的字符串)。该函数还接收一个“length”参数,以确保它最终终止 基本上,这是生成一种语言(特定长度)接受的所有可能字符串 现在,我让这个工作,甚至相当好和干净,但我想知道是否有更好的方法来做到这

我最近完成了一个项目,其中我正在生成字符串列表,我想知道最好的方法是什么

字符串生成是上下文敏感的,以确定是否可以接受(这是游戏中的一系列游戏,因此您必须知道最后一个游戏是什么)

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

基本上,这是生成一种语言(特定长度)接受的所有可能字符串

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


任何想法都将不胜感激。

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

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

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]]
键入sym=Xa | Xb | Xc//终端符号
键入word=sym list//一组终端
键入gen=int->sym list seq//生成给定长度的单词
///检查长度后,将上一个符号传递给生成器。
let(+>):sym->(sym->gen)->gen=
funxgl->if lx::xs}
让nil=seq{yield[]}//只生成空单词
让(| | |)xs ys l=Seq.append(xs l)(ys l)//两个生成器的并集
让notAccepted=Seq.empty//不生成任何内容
让tryAll g=Xa+>g | | | | Xb+>g | | | Xc+>g//从任何符号开始运行g
//非终端发电机。每个符号都将前一个符号作为参数,
//并生成(可能为空)符号列表序列。
设rec gR=函数Xa->Xb+>gS | | | Xc+>gR | | | nil
|Xc->Xb+>gS | |->不接受
和gS=函数Xb->Xa+>gR | |->未接受
让genTop=tryAll gR//顶级生成器以gR开头,带有任何符号
让words=genTop 4//生成长度不超过4的单词
//val单词:seq
//=seq[[Xa;Xb;Xa];[Xa;Xc;Xb;Xa];[Xa];[Xc;Xb;Xa]]

您可以发布您创建的任何代码吗?这将更容易理解你的意思。非常有趣的答案。。。我不知道我在做什么,我最初发布了这个,但我后来进入了一个象棋游戏,这将有助于一点。。。谢谢