78 lines
2.9 KiB
Markdown
78 lines
2.9 KiB
Markdown
---
|
||
author: usbharu
|
||
draft: false
|
||
categories:
|
||
- 技術
|
||
date: 2024-11-17T20:26:23+09:00
|
||
tags:
|
||
- Kotlin
|
||
- KMP
|
||
- Markdown
|
||
keywords:
|
||
- Kotlin
|
||
- Markdown
|
||
- KMP
|
||
title: Kotlin MultiplatformなMarkdownパーサを作った
|
||
relpermalink: posts/2024-11-17/
|
||
url: posts/2024-11-17/
|
||
decription: Kotlin MultiplatformなMarkdownパーサを作った
|
||
---
|
||
|
||
なんとなくパーサを作って遊びたくなったので作り始めたら意外と楽しくて、夢中で作ってました。制作期間は5日ぐらいです。パーサコンビネータを使わずにパーサを書くこと自体がかなり久しぶりだったのでウンコード量産しました。気が向いたら改善したいです。
|
||
|
||
[markdown-kt](https://github.com/usbharu/markdown-kt)
|
||
|
||
## markdown-kt
|
||
|
||
全部で1000行程度で、Lexerはテーブルと参照以外の基本的な構文に対応しています。パーサは打ち消し線、HTML、コードブロック、チェックボックスが未対応です。コード生成部分は作ってないのでパースできるだけ、いつかHTML生成とかもやってみたい
|
||
|
||
せっかく作るならなんか特徴入れたいなと思って、全角記号に対応したLexerにしてみました。
|
||
![全角半角両方書かれたLexer](lexer.png)
|
||
|
||
雑に全角対応してあります。
|
||
|
||
### Kotlinのwhenについて
|
||
|
||
Kotlinは`when`を使うことで複数のor条件を簡単に書くことができますが、今回は使えなかったので普通に`||`演算子使っています。
|
||
|
||
```kotlin
|
||
val foo: String
|
||
|
||
fun isBar(string:String): Boolean{
|
||
return string == "bar"
|
||
}
|
||
|
||
when(foo){
|
||
"hoge", "fuga" -> TODO() //複数の条件を簡単に書くことができる
|
||
isBlank() -> TODO() //error 書けない
|
||
isBar(foo) -> TODO() //error 書けない
|
||
}
|
||
|
||
when{
|
||
foo == "hoge" || foo == "fuga" -> TODO() //書ける
|
||
foo.isBlank() -> TODO() //書ける
|
||
isBar(foo) -> TODO() //書ける
|
||
}
|
||
```
|
||
|
||
あとはRustみたいに書けるようになったら便利だなぁ~と思いながら書いていました。
|
||
|
||
```kotlin
|
||
val foo: String
|
||
val flagA: Boolean
|
||
|
||
when(foo,flagA){
|
||
("hoge",false) -> TODO()
|
||
("hoge",true) -> TODO()
|
||
}
|
||
```
|
||
|
||
### while
|
||
|
||
どうやら今回whileとdo-whileを合計28回使っているようです。というかdo-whileを実際に書く事があるとは思わなかった
|
||
|
||
ラベル付きwhileも何回か登場していて、まともにコードを書いていたら使わないであろう構文を何度か使えて楽しかったです。ノリと勢いで実装したのでかなりウンコードなので、1週間後の自分はもう読めないと思います。
|
||
|
||
### その他
|
||
|
||
MisskeyのMFMをパースしようとしたときに身に着けた無駄な知識が意外と役に立ったので、今度はRustで実装するとか、MFMのパース再チャレンジとかしたいな~と思いました。あとはトークンとかASTに行番号とかを持たせてエラー表示とかをやってみたい |