日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构成为小语言

發(fā)布時間:2024/3/24 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构成为小语言 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

數(shù)據(jù)結(jié)構(gòu)成為小語言

?

面向語言的開發(fā)并不一定意味著,一定要自己開發(fā)解析器或編譯器。這就是說,我們將在下一章學(xué)習(xí)創(chuàng)建解析器,然后,把這樣的解析器和本章介紹的方法照結(jié)合起來,去構(gòu)建一個簡單的編譯器。可以通過創(chuàng)建數(shù)據(jù)結(jié)構(gòu)和函數(shù)或模塊,就能夠做很多事,數(shù)據(jù)結(jié)構(gòu)描述了準備做什么,而函數(shù)或模塊定義了如何解釋結(jié)構(gòu)。

幾乎可以用任何語言創(chuàng)建數(shù)據(jù)結(jié)構(gòu)來表示一個程序,但是 F# 更適合。F# 的文字列表和數(shù)組很容易定義,不要求龐大的類型注解;它的聯(lián)合類型能夠創(chuàng)建結(jié)構(gòu),來表達相關(guān)的概念,但卻不一定要包含相同類型的數(shù)據(jù),可以用它來創(chuàng)建樹型結(jié)構(gòu),這在創(chuàng)建語言時是非常有用的;最后,由于函數(shù)可以看作是值,因此,我們可以很容易把函數(shù)嵌入到數(shù)據(jù)結(jié)構(gòu)中,這樣,F# 的表達式就能成為語言的一部分,通常作為一個動作,來響應(yīng)語言的特定條件。

我們先來看一下在FSharp.PowerPack.dll 中預(yù)定義的 DSL,通過 Arg(參數(shù))模塊能夠快速構(gòu)建命令行參數(shù)解析器。它是通過 F# 的聯(lián)合和列表類型而實現(xiàn)的,先創(chuàng)建小語言,然后,用參數(shù)模塊中的大量函數(shù)進行解釋。

參數(shù)模塊公開了一個元組類型argspec,它由兩個字符串和一個聯(lián)合類型 spec 組成。元組中的第一個字符串指定了命令行參數(shù)的名字,元組中的第二項是聯(lián)合類型 spec,它指定了參數(shù)的內(nèi)容,例如,它可以指定后面跟著的是字符串值,或者只是一個標(biāo)志;它還可以指定如果發(fā)現(xiàn)命令行標(biāo)記,應(yīng)該做什么。元組中最后的字符串是關(guān)于這個標(biāo)志做什么的文本描述,當(dāng)命令行參數(shù)錯誤時會打印到控制臺,對程序員來說也是一個有用的注釋。

參數(shù)模塊公開了兩個函數(shù)用于解析參數(shù):parse,它解析在命令行中傳入的命令;和parse_argv,它要求直接傳遞參數(shù)給它。我們應(yīng)該傳遞描述命令行參數(shù)的 argspec 類型列表的函數(shù),所有被傳遞給函數(shù)的命令行參數(shù)都沒有前綴 -,最后,是描述用法的字符串。

這個模塊還公開了第三個函數(shù),可以傳遞argspec 類型的列表,并直接寫出用法。

下面的例子演示了如何以這種方法構(gòu)建參數(shù)解析器,把從命令行收集的參數(shù)保存到標(biāo)識符中準備以后使用,這里,是把它們定到控制臺:

?

let myFlag = ref true

let myString = ref ""

let myInt = ref 0

let myFloat = ref 0.0

let (myStringList : string list ref) = ref []

?

let argList =

??? [ ("-set", Arg.Set myFlag, "Sets the value myFlag");

????? ("-clear", Arg.Clear myFlag, "Clears the value myFlag");

????? ("-str_val", Arg.String(fun x -> myString:= x), "Sets the value myString");

????? ("-int_val", Arg.Int(fun x -> myInt :=x), "Sets the value myInt");

????? ("-float_val", Arg.Float(fun x -> myFloat:= x), "Sets the value myFloat") ]

?

ifSystem.Environment.GetCommandLineArgs().Length <> 1 then

? Arg.parse

??? argList

??? (funx -> myStringList := x :: !myStringList)

??? "Argmodule demo"

else

? Arg.usage

??? argList

??? "Argmodule demo"

? exit1

?

printfn "myFlag: %b" !myFlag

printfn "myString: %s" !myString

printfn "myInt: %i" !myInt

printfn "myFloat: %f" !myFloat

printfn "myStringList: %A"!myStringList

?

當(dāng)運行前面的代碼,沒有命令行參數(shù),或者命令行參數(shù)錯誤時,程序會輸出下面的結(jié)果:

?

Arg module demo

? -set:Sets the value my_flag

? -clear:Clears the value my_flag

? -str_val<string>: Sets the value my_string

? -int_val<int>: Sets the value my_int

? -float_val<float>: Sets the value my_float

? --help:display this list of options

? -help:display this list of options

?

當(dāng)用下面的命令行運行前面的示例時:

?

args.exe -clear -str_val "helloworld" -int_val 10 -float_val 3.14 "file1" "file2""file3"::

?

輸出如下:

?

myFlag: false

myString: hello world

myInt: 10

myFloat: 3.140000

myStringList: ["file3";"file2"; "file1"]

?

我特別喜歡這樣的 DSL,因為它使問題更清晰,程序需要什么參數(shù),如果接收到參數(shù),應(yīng)該進行什么樣的處理。幫助文本也保存在這個結(jié)構(gòu)中,有兩個目的:如果命令行參數(shù)有錯誤,函數(shù)會自動輸出一個幫助消息;當(dāng)我們忘記什么參數(shù)時,可以提醒。我也喜歡用這種方式創(chuàng)建命令行解析器,因為,我用命令語言寫過幾個命令行解析器,那可不是令人滿意的體驗,最終必須寫大量的代碼,詳細說明如何拆分命令行。如果你用.NET 寫過代碼,那么,通常會花太多的時間在調(diào)用字符串類型的IndexOf 和Substring 方法。

總結(jié)

以上是生活随笔為你收集整理的数据结构成为小语言的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。