2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【地獄】パーサコンビネータから作ろう...

2
Last updated at Posted at 2026-04-29

私の使っているライブラリ、FParsec
しかし扱いが難しい...
ならいっそのこと、作ってしまえ!

そんなわけで、パーサコンビネータPsictreを簡易ながらも作りました

誕生秘話①

今まで、私は以下のDSLを作りました

  • ParserScript (ファイル消失)
  • UCCScript (バグあり・可読性皆無・孤立したDSL)
  • ChainCC / CC+ (孤立したDSL)

CC+にて開発言語のF#と連携させる試みがありましたが、できることがほぼありませんでした

今回のPsictreはF#用ライブラリとなっています。別のファイルに専用のスクリプトを書くことはしません
これで、F#の力を100%引き出すことができます

誕生秘話②

ある時、私はこう考えました

パースした後のASTを型推論でもう一度組み立て直すのは面倒くさい!

だったら、パースと同時に型推論をやってしまおうではないか


しかしながら、Psictreに型推論エンジンを持たせるのは難しいです
理由として以下があげられます

  • 作る言語が動的型かもしれない
  • オブジェクトの考え方が違うかもしれない

仮にPsictreをNugetパッケージとして公開したとしましょう
Psictreは私の言語のために作っているわけですから、フレーム指向専用にできています
それでは、オブジェクト指向言語は作れなくなってしまいます

そのため、Psictreでは型推論をアシストする機能を提供するだけにしました

書き味

PsictreはF#特有の「コンピューテーション式」を使います

type Fruits =
    | Apple
    | Orange

[<EntryPoint>]
let main =
    let wspace = parse {
        let! _ = pchar ' '
    }

    let appleOrOrange =
        parse {
            let! _ = pstring "apple")
            return Apple
        }
        <|>
        parse {
            let! _ = pstirng "orange"
            return Orange
        }
    let p = parse {
        let! first, _ = appleOrOrange
        let! list, _ = many (parse {
            let! _ = wspace
            let! res, _ = appleOrOrange
            return res
        })
        return first :: list
    }

    let input = "orange apple apple orange apple"
    
    let result = run p input
    
    let countOfApples =
        result
        |> List.filter ((=) Apple)
        |> List.length
    let countOfOranges =
        result
        |> List.filter ((=) Orange)
        |> List.length
    
    printfn "apple=%i, orange=%i" countOfApples countOfOranges
    // => "apple=3, orange=2"
    
    0

終わりに

これから、型推論のアシスト機能追加に移ります

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?