Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Wasmで動くRust製マークダウンパーサーを自作した話
Search
yud0uhu
July 01, 2023
Programming
1
44
Wasmで動くRust製マークダウンパーサーを自作した話
Zennはこちら
https://zenn.dev/denham/articles/f602bd105ecb69
隅田川.dev vol.1 by July 1, 2023
yud0uhu
July 01, 2023
Tweet
Share
More Decks by yud0uhu
See All by yud0uhu
早朝の渋谷の青さ、あるいは溺れた人を助ける為に飛び込んだ海の向こう側に見る、自己覚知と自己開示の尊さ
yud0uhu
1
580
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
1
320
非デザイナーのフロントエンドエンジニアがOOUIを考える
yud0uhu
9
5.5k
2023年の ゼロランタイムCSS in JS⚡️ を考える
yud0uhu
5
4.8k
Vue3/Electronで自作したマークダウンエディタをVue3/Tauriにリプレイスした話
yud0uhu
2
2.8k
入社半年を迎える新米エンジニアがカンファレンス・勉強会から得た学び
yud0uhu
0
1k
Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
yud0uhu
0
1.2k
Rustでつくって学ぶProtocol Buffers
yud0uhu
1
180
ブログを自作した話
yud0uhu
1
28
Other Decks in Programming
See All in Programming
Improving my own Ruby thereafter
sisshiki1969
1
130
あなたとJIT, 今すぐアセンブ ル
sisshiki1969
1
760
MLH State of the League: 2026 Season
theycallmeswift
0
180
Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models
tomohisa
0
220
サイトを作ったらNFCタグキーホルダーを爆速で作れ!
yuukis
0
720
[FEConf 2025] 모노레포 절망편, 14개 레포로 부활하기까지 걸린 1년
mmmaxkim
0
1.4k
TROCCO×dbtで実現する人にもAIにもやさしいデータ基盤
nealle
0
390
AI時代のドメイン駆動設計-DDD実践におけるAI活用のあり方 / ddd-in-ai-era
minodriven
25
9.4k
testingを眺める
matumoto
1
130
A Gopher's Guide to Vibe Coding
danicat
0
190
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
3
1.8k
AIエージェント開発、DevOps and LLMOps
ymd65536
1
370
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
A Modern Web Designer's Workflow
chriscoyier
696
190k
Embracing the Ebb and Flow
colly
87
4.8k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.6k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
23
1.4k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Why Our Code Smells
bkeepers
PRO
339
57k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
252
21k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Transcript
Wasmで動くRust製マーク ダウンパーサーを自作した話 0Yu 隅田川.dev
0yu(おゆ,ぜろゆー) 好きな技術 • Webフロントエンド、Rust 趣味 • 映画鑑賞・旅行・ゲーム etc • 最近はハイラルの勇者をしています
自己紹介 っっっz yud0uhu 2
• Rustと言語処理系の勉強のため、簡易的なマークダウンパーサーを スクラッチで実装した • 生成したWASMをNuxt3+Viteの環境で動かした はじめに
字句解析 • テキストを字句の列(トークン)に分解する こと • 字句解析を行うプログラムを字句解析器 (lexerまたはtokenizer)と呼ぶ 言語処理系の概要
構文解析 • トークン列を抽象構文木(abstract syntax treeまたはAST)に変換する • 抽象構文木とは、言語の構文を解釈し、 データ構造を取り出した(抽象化した)木構 造のこと 言語処理系の概要
意味解析 • 構文木の意味を解析する • コンパイラでは、この段階で中間コード を生成する 言語処理系の概要
最適化 • 中間コードを変形して、効率のよいプロ グラムに変換すること • コンパイラでは、パースしたソースコー ドから無駄な処理を分析し、コード最適 化を行う 言語処理系の概要
コード生成 • 抽象構文木を入力とし、ターゲットとな る言語のコードを生成する • コンパイラでは、この段階で中間コード をネイティブコード(ターゲットのCPUが 解釈できる実行形式のバイナリコード)に 変換する 言語処理系の概要
マークダウンテキストを入力とし トークンに分割(字句解析) →ASTに変換(構文解析) →HTMLを生成(コード生成) できるようにする パーサーの構成
• 字句の列(トークン)を定義する • 入力されたテキストをトークンに分割する 字句解析器(Lexer)の実装
実装するマークダウンタグ • 見出し(<h1>~<h6>) • 太字(<b>) • 斜体(<i>) • 引用(<blockquotes>) •
リスト(<ul>,<li>) 字句解析器(Lexer)の実装
トークンを定義する • Heading,Bold,Italic,BlockQu otes,Lists の5つのトークン を定義する 字句解析器(Lexer)の実装
字句解析(Tokenize)する • 字句解析は関数lexが担う • 字句解析のための文字列操作 はイテレータで行う ◦ イテレータとは、複数個 の要素の集まり(配列・リ ストなど)から、次の要素
を一つずつ順に取り出す インターフェースのこと 字句解析器(Lexer)の実装
fn next(&mut self) -> Option<Self::Item> • nextはイテレータを消費するメソッド • 呼び出されるたびにイテレータを消費してSome に包まれた一要素を
返し、繰り返しが終わるとNoneを返す ◦ next()で入力された文字列を一つずつ取り出し、変数cに格納す る 字句解析器(Lexer)の実装
• 見出しタグの判定では、頭文字が#と (半角スペース)で始まる語句を 識別できるようにしたい • 変数cが#、in_boldがfalse(太字ではない)でin_italicがfalse(斜体で はない)のときにのみ処理するようなパターンマッチングを書く 字句解析器(Lexer)の実装
• peekはイテレータを消費する前に、前もって参照を返す(新たなイテ レータPeekable<T>を返す)メソッド • 行頭に#が連続して出現する時(chars.peek()とSome(&'#')が等しい 時)、一文字ずつ文字列を読み進めながら、levelを1ずつ加算 字句解析器(Lexer)の実装
• peekはイテレータを消費する前に、前もって参照を返す(新たなイテ レータPeekable<T>を返す)メソッド • 行頭に#が連続して出現する時(chars.peek()とSome(&'#')が等しい 時)、一文字ずつ文字列を読み進めながら、levelを1ずつ加算 字句解析器(Lexer)の実装
• levelの値に応じて見出しのレベルを判定 • 適切なToken::Headingをtokensに追加し、見出しをトークン化 字句解析器(Lexer)の実装
• 半角スペースの後に続くテキストがTokenの値に正しく解釈されるよ うにしたい • 現在の文字が半角スペースのときにのみ、charsから文字を取り出す 処理を書く 字句解析器(Lexer)の実装
• トークンから抽象構文木(AST)を構築する • ASTはノードが集まってできた木構造 ◦ Heading(見出し)タグは、Heading Level(見出しレベル)ノード とText(文字列)ノードが集まってASTを構築する 構文解析器(Parser)の実装
• トークン配列からASTNodeを構築 構文解析器(Parser)の実装
• Token::Headingをパースして、AstNode::Headingに変換 構文解析器(Parser)の実装
• 構築されたASTをHTMLに変換する ◦ AstNode型のスライスを参照するast: &[AstNode]を引数に持 ち、Stringを返す関数generate_htmlを定義 コード生成器(Generator)の実装
• パターンマッチング→ASTのノードをhtmlタグにフォーマットし、 result配列に追加する処理を愚直に書く コード生成器(Generator)の実装
• 関連関数text_to_tokenで呼び出す レンダリング
• wasm-packでビルドする ◦ Cargo.tomlで環境設定を行う WASMの生成
• lib.rsに#[wasm_bindgen]アトリビュートを付与 WASMの生成
• % rustup target add wasm32-unknown-unknownでターゲット アーキテクチャを追加して% wasm-pack buildする •
target/wasm32-unknown-unknown/release に、最適化されたビ ルドバイナリが出力される WASMの生成