【入門編】 HTMLパーサーのトークン化プロセス – Webブラウザの仕組み実践ガイド

こんにちは!Webブラウザの仕組みの旅へようこそ。
フロントエンドのアーキテクトとして日々いろんなコードと格闘していますが、今回は「ブラウザが画面を表示するまでの一番最初の関所」、HTMLパーサーのトークン化プロセスについてお話ししますね。

「HTMLの解析? DOMツリー? なんだか難しそう……」って身構えちゃいましたか?
大丈夫ですよ、安心してください。今日はお買い物のレシートや、言葉を単語に分解するパズルみたいな身近な例えを交えながら、とっても優しく紐解いていきます。

ブラウザの頭の中を覗く冒険、一緒に楽しんでいきましょう!

—

そもそも、ブラウザはHTMLをどう見ているの?

私たちが普段テキストエディタで書いているHTMLファイル(`index.html`など)は、人間から見れば「ただの文字の羅列」ですよね。




私のブログ

こんにちは!


でも、冷徹な(そして超高速な)Webブラウザにとって、このコードはただの「1文字ずつの長い文字列(ただの文字の塊)」でしかありません。
ブラウザは、この文字の塊をそのままでは理解できないんです。「お、ここに `

` があるから大見出しだな」と理解するためには、文字を意味のある最小単位に「ばらして整理」してあげる必要があります。

この、「ただの長い文字列を、意味のあるパーツ(トークン)に分解していく作業」こそが、今回主役にする「トークン化(字句解析)」と呼ばれるプロセスなんです。

—

例え話:レジの「バーコード読み取り」と「品目シール」

このトークン化のプロセス、何かに似ていると思いませんか?
そう、スーパーのお買い物のレジの仕組みにすごくよく似ています。

お買い物カゴに入っているのは、形も大きさもバラバラの商品(HTMLの文字列)です。
レジの店員さん(HTMLパーサー)は、商品を一つひとつバーコードリーダーでピッ!と読み取っていきます。

  • 「あ、これは『牛乳』っていう商品タグだな」
  • 「こっちは『パン』っていう商品タグだな」
  • 「これはカゴの中の商品の名前じゃなくて、ただの『お惣菜のパッケージの文字』だな」

バーコードをピッ!と読み取るたびに、レジの画面には「商品名:牛乳、価格:200円」という意味のある単位でデータが登録されていきますよね。

ブラウザのトークン化もこれと全く同じです。
ブラウザはHTMLという長い文字列のトンネルを左から右へ1文字ずつ(あるいは数文字ずつ)進みながら、「あ、ここはタグの始まりだ!」「ここは中身のテキストだな!」と切り分けて、ペタペタと「意味のシール(トークン)」を貼っていくのです。

—

トークン化の舞台裏:ステートマシン(状態の切り替え)ってなに?

さて、ここから少しだけ裏側の仕組みをのぞいてみましょう。
ブラウザは、文字を切り分けるために「ステートマシン(状態機械)」という仕組みを使っています。

難しそうに聞こえますが、要するに「今のモードは何か?」を常に切り替えているだけです。例えば、以下のようなモード(状態)を行ったり来たりしています。

1. データ状態(Data State): 普通のテキストを読んでいるモード
2. タグオープン状態(Tag Open State): 「`<`」を見つけて、「おっ、何かタグが始まるぞ!」と身構えるモード 3. タグ名状態(Tag Name State): 「`h1`」や「`p`」といったタグの名前を読んで、「あ、見出しタグだな」と確定させるモード
4. 属性名状態(Attribute Name State): `class=”box”` の `class` の部分を読んでいるモード

ブラウザは、HTMLの文字列を左から右へ1文字ずつスキャンしながら、今自分がどのモードにいるべきかをものすごいスピードで切り替えています。

トークンの5つの代表的な顔ぶれ

こうして文字を切り分けた結果、ブラウザは以下のような「トークン(部品)」のリストを作ります。

  • StartTag(開始タグ)トークン: `

    ` や `

    ` など
  • EndTag(終了タグ)トークン: `

    ` や `

` など

  • Character(文字)トークン: タグに挟まれた実際のテキスト(「こんにちは!」など)
  • Comment(コメント)トークン: `` の部分
  • EOF(End Of File)トークン: 「もうファイルの最後まで読み終わったよ!」という合図
  • ブラウザはこのトークンの束を次々に作り出し、次のステップである「DOMツリーの構築」へとバトンタッチしていくのです。

    —

    実践:ブラウザの気分になってHTMLを分解してみよう

    百聞は一見にしかず。私たちが普段書いている簡単なHTMLコードを、ブラウザがどのようにトークンに分解しているのか、実際に目で見てみましょう。

    以下のサンプルコードを見てください。

    ハロー、ワールド!

    このコードをブラウザの「トークン化プロセス」に通すと、内部的には次のようなトークンの流れ(イメージ)に変換されます。

    1. StartTag トークン

    • タグ名: `div`
    • 属性: `class=”greeting”`

    2. Character トークン

    • 文字列: `\n ` (改行やインデントのスペース)

    3. StartTag トークン

    • タグ名: `p`

    4. Character トークン

    • 文字列: `ハロー、ワールド!`

    5. EndTag トークン

    • タグ名: `p`

    6. Character トークン

    • 文字列: `\n`

    7. EndTag トークン

    • タグ名: `div`

    8. EOF トークン (おしまい!)

    「おや、タグとタグの間の改行やスペースも、ちゃんと『Characterトークン』として読み込まれているんだな」って気づきましたか?
    そうなんです!ブラウザは私たちが書いたコードの空白や改行すらも、サボらずにちゃんとトークンとして受け取っているんです。これが後のDOMツリーに影響を与えることもあるので、地味だけどとても重要なポイントですよ。

    —

    つまずきポイント:HTMLが多少崩れていても動く理由

    Web制作を始めたばかりの頃、「あれ、閉じタグの `

    ` を書き忘れたのに、なぜか画面がちゃんと表示されるぞ?」と不思議に思ったことはありませんか?

    実は、ここにもトークン化と、それに続くパーサーの「優しさ(エラー回復機能)」が隠されています。

    昔のインターネット黎明期、Webサイトのコードは今よりもっとめちゃくちゃでした。タグが閉じられていなかったり、順番がぐちゃぐちゃだったり……。もしブラウザが「あ、文法エラーだ!画面を表示するのをストップします!」と冷たくシャットアウトしてしまったら、世の中のほとんどのWebサイトは真っ白で何も見えなくなっていたでしょう。

    そのため、ブラウザのHTMLパーサー(およびトークナイザー)は、「多少の書き間違いがあっても、文脈から推測して勝手に補完してトークンを作る」という、ものすごく高度で泥臭いリカバリー機能を持っています。

    例えば、`太字と斜体` のようにタグが交差してしまっていても、ブラウザの仕様(HTML Living Standard)には「こういう場合はこう解釈しなさい」というルール(エラーハンドリングの仕様)が何百ページにもわたって細かく定められています。

    とはいえ、ブラウザに余計な推測の苦労をさせないためにも、綺麗な正しいHTMLを書くことに越したことはありません。「ブラウザは頑張ってカバーしてくれているんだな、でも綺麗に書こう!」と心がけてあげてくださいね。

    —

    まとめ:ブラウザの職人技に感謝を込めて

    今回は、HTMLパーサーの「トークン化プロセス」について、ブラウザの頭の中をのぞきながら解説してきました。

    私たちが何気なくブラウザにURLを入力してWebサイトを表示したとき、その裏側では、ブラウザがこのトークン化という職人技をコンマ数秒の間に何万回、何百万回と繰り返しています。

    そう思うと、普段何気なく見ているWebブラウザが、少しだけ愛おしく、頼もしく感じられませんか?
    今回の記事が、あなたのWeb開発の引き出しを広げる小さなスパイスになれば、チーフアーキテクトとしてこんなに嬉しいことはありません。

    それでは、また次回のブラウザ探検でお会いしましょう!

    コメント

    タイトルとURLをコピーしました