2

私は約 2 か月間 F# を初めて使用し、最近FParsec チュートリアルを終了し、さらに例を探し始めました。読めば読むほど混乱し、スタイルへの言及を目にするようになりました。もっとスタイルを探して、このリストを思いついた.

  • コンビネータ スタイル
  • モナディックスタイル
  • 矢印のスタイル
  • ダイレクトスタイル

誰かがすべてのスタイルをリストし、それぞれが一般的な問題でどのように機能するかを説明および実証できますか。

“(abc 
  (b CDEF 
   (de 1 E) 
   (f 234)
  ) 
  (h 3) 
  (jkl H) 
 )”  

の中へ

[Lower "abc";
 Group[Lower "b"; Upper "CDEF"; 
  Group [Lower "de"; Number "1"; Upper "E"];
  Group [Lower "f"; Number "234"]]; 
 Group [Lower "h"; Number "3"];
 Group [Lower "jkl"; Upper "H"]
]

使用する

Type out = 
| Lower of string
| Upper of string
| Number of string
| Group of out list

編集

FParsecのコメントと区切り文字ベースの構文から、コンビネータとモナド スタイルを拾いました。

Direct Style は常に Direct Style Monadic Parser として表示されます

アロー スタイルがParsec に登場: Direct Style Monadic Parser Combinators For The Real World私はこれをすべて読んでいません。

編集

提案ごと

コンビネータ スタイル

type out =
| Lower of string
| Upper of string
| Number of string
| Group of out list

type Parser = Parser<out, unit>

let isUpper = fun c -> isAsciiUpper c 
let upper : Parser = 
    many1Satisfy isUpper .>> ws 
    |>> fun x -> Upper(x)

let isLower = fun c -> isAsciiLower c 
let lower : Parser= 
    many1Satisfy isLower .>> ws
    |>> fun x -> Lower(x)

let isNumber = fun c -> isDigit c 
let number : Parser =
    many1Satisfy isNumber .>> ws
    |>> fun x -> Number(x)

let groupRef, groupImpl = createParserForwardedToRef()

let item : Parser = 
    lower <|> upper <|> number <|> groupRef

let items = 
    many item .>> ws 
    |>> fun x -> Group(x)

do groupImpl := between (pchar '(') (pchar ')') items .>> ws 

let test () =
    match run groupRef "(abc (b CDEF (de 1 E) (f 234)) (h 3) (jkl H) )" with
    | Success(result, _, _)   -> printf "Success: %A" result
    | Failure(errorMsg, _, _) -> printf "Failure: %s" errorMsg
4

1 に答える 1

1

モナディックスタイル

type out =
| Lower of string
| Upper of string
| Number of string
| Group of out list

type Parser = Parser<out, unit>

let isUpper = fun c -> isAsciiUpper c 
let upper : Parser =  parse {
    let! x = many1Satisfy isUpper 
    do! ws 
    return Upper(x)
    }

let isLower = fun c -> isAsciiLower c 
let lower = parse {
    let! x = many1Satisfy isLower
    do! ws 
    return Lower(x)
    }

let isNumber = fun c -> isDigit c 
let number = parse {
    let! x = many1Satisfy isNumber
    do! ws 
    return Number(x)
    }

let groupRef, groupImpl = createParserForwardedToRef()

let group =  parse {
    let! x = groupRef
    do! ws
    return x
    }

let item  = 
    lower <|> upper <|> number <|> group

let items = parse {
    let! x = many item   
    do! ws        
    return Group(x)
    }

do groupImpl := between (pchar '(') (pchar ')') items

let test () =
    match run group "(abc (b CDEF (de 1 E) (f 234)) (h 3) (jkl H) )" with
    | Success(result, _, _)   -> printf "Success: %A" result
    | Failure(errorMsg, _, _) -> printf "Failure: %s" errorMsg
于 2012-04-16T01:17:46.353 に答える