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
25
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
240
非デザイナーのフロントエンドエンジニアがOOUIを考える
yud0uhu
9
5k
2023年の ゼロランタイムCSS in JS⚡️ を考える
yud0uhu
5
4.6k
Vue3/Electronで自作したマークダウンエディタをVue3/Tauriにリプレイスした話
yud0uhu
2
2.4k
入社半年を迎える新米エンジニアがカンファレンス・勉強会から得た学び
yud0uhu
0
920
Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
yud0uhu
0
1.1k
Rustでつくって学ぶProtocol Buffers
yud0uhu
1
96
ブログを自作した話
yud0uhu
1
18
Rustで自作しながら学ぶ仮想DOM
yud0uhu
1
23
Other Decks in Programming
See All in Programming
Pulsar2 を雰囲気で使ってみよう
anoken
0
230
Conform を推す - Advocating for Conform
mizoguchicoji
3
690
第3回 Snowflake 中部ユーザ会- dbt × Snowflake ハンズオン
hoto17296
4
370
CNCF Project の作者が考えている OSS の運営
utam0k
6
710
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
210
技術を根付かせる / How to make technology take root
kubode
1
250
Multi Step Form, Decentralized Autonomous Organization
pumpkiinbell
1
730
動作確認やテストで漏れがちな観点3選
starfish719
6
1k
2,500万ユーザーを支えるSREチームの6年間のスクラムのカイゼン
honmarkhunt
6
5.3k
昭和の職場からアジャイルの世界へ
kumagoro95
1
370
もう僕は OpenAPI を書きたくない
sgash708
4
1.4k
SpringBoot3.4の構造化ログ #kanjava
irof
2
990
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Writing Fast Ruby
sferik
628
61k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
A Tale of Four Properties
chriscoyier
158
23k
Navigating Team Friction
lara
183
15k
The Language of Interfaces
destraynor
156
24k
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の生成