Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Wasmで動くRust製マークダウンパーサーを自作した話
Search
yud0uhu
July 01, 2023
Programming
1
48
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
Webブラウザ向け動画配信プレイヤーの 大規模リプレイスから得た知見と学び
yud0uhu
0
300
早朝の渋谷の青さ、あるいは溺れた人を助ける為に飛び込んだ海の向こう側に見る、自己覚知と自己開示の尊さ
yud0uhu
1
710
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
1
340
非デザイナーのフロントエンドエンジニアがOOUIを考える
yud0uhu
9
5.7k
2023年の ゼロランタイムCSS in JS⚡️ を考える
yud0uhu
5
4.9k
Vue3/Electronで自作したマークダウンエディタをVue3/Tauriにリプレイスした話
yud0uhu
2
2.9k
入社半年を迎える新米エンジニアがカンファレンス・勉強会から得た学び
yud0uhu
0
1k
Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
yud0uhu
0
1.2k
Rustでつくって学ぶProtocol Buffers
yud0uhu
1
220
Other Decks in Programming
See All in Programming
CSC509 Lecture 14
javiergs
PRO
0
220
AIコードレビューがチームの"文脈"を 読めるようになるまで
marutaku
0
320
ViewファーストなRailsアプリ開発のたのしさ
sugiwe
0
400
20251127_ぼっちのための懇親会対策会議
kokamoto01_metaps
2
420
MAP, Jigsaw, Code Golf 振り返り会 by 関東Kaggler会|Jigsaw 15th Solution
hasibirok0
0
220
非同期処理の迷宮を抜ける: 初学者がつまづく構造的な原因
pd1xx
1
640
モダンJSフレームワークのビルドプロセス 〜なぜReactは503行、Svelteは12行なのか〜
fuuki12
0
200
【Streamlit x Snowflake】データ基盤からアプリ開発・AI活用まで、すべてをSnowflake内で実現
ayumu_yamaguchi
1
110
WebRTC、 綺麗に見るか滑らかに見るか
sublimer
1
150
AIエージェントを活かすPM術 AI駆動開発の現場から
gyuta
0
240
『実践MLOps』から学ぶ DevOps for ML
nsakki55
2
560
Google Antigravity and Vibe Coding: Agentic Development Guide
mickey_kubo
2
140
Featured
See All Featured
Speed Design
sergeychernyshev
33
1.4k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.2k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Balancing Empowerment & Direction
lara
5
790
Unsuck your backbone
ammeep
671
58k
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.8k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
253
22k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.8k
Why You Should Never Use an ORM
jnunemaker
PRO
60
9.6k
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の生成