Let's 4 フロントフォーク交換(CA41A)

調布市が原付のナンバーをリニューアルするということで、一桁ナンバーの抽選に応募した結果1番のナンバーを手に入れたオンボロLet'sくん。
GSX250Rを手に入れてからというものの、めっきり出番が少なくなってしまい実家の移動用として第二の人生を送ってもらっているわけですが、フロントのサスペンショのフォークがあまりにも残念なことになってきたので、交換しました。

f:id:kat0h:20260303215540j:image

型式はCA41Aで2007年式らしいので、もうすぐ20年選手ですがエンジンなどは比較的快調。東京長野間の200kmのツーリングも3度こなし、ヤフオクで手に入れてから3000kmほどは一緒に走りました。初めて手に入れた自由な移動手段なので少しは思い入れもあり、これから少しずつメンテして貴重なナンバーを維持したいです。

大きなトラブルもなく走っていますが、随所に素人修理の痕跡が見られすぐ挙げられるだけでも次のような問題があります(ありました)。

  • ボディの塗装 
    • しまりんカラーで、嫌いではないけど
  • 足置きのプラスチック部品の割れ
    • ついでに足元のカバーを開けたら謎に穴が開けられていた
    • 螺子があり合せの謎ネジ
  • ドライブベルトの劣化(交換済み)
    • ついでにウェイトローラーも
  • エアクリーナーボックスのタッピングが舐め気味
  • ヘッドライト劣化(交換済み)
  • キックが渋い
    • これは自分が開けたときしっかりグリスを入れなかったから
    • どうせFI車だしセル以外で掛けることないだろ
  • サビ
    • とはいえ、構造的には問題ないレベルなので軽度っちゃ軽度
  • 雨の日にかかりが悪くなる
    • なぜ?チョークコイルをちょっと疑っている
    • しかし、一度かかれば次の始動も快調なので問題ではない
  • メインハーネスの皮膜の劣化
    • プラスチックは脆い
  • ネジのサビ
    • 開ける度に舐めが進行している
  • グリップが汚ない
  • シートが汚ない
    • 座ってもズボンは汚れない。見た目だけ
  • スピードメーターケーブルの破断(修理済み)
  • フロントサスペンションがカス
    • 持病のブーツ裂け
  • リアタイヤに空気を入れずらい
    • どう入れろと?
  • マフラーカバー割れ
    • 雪の箱根にノーマルタイヤで突っこんだときに、手押しでUターンしようとしてこかした
  • 雑にメーター回りから12Vを取って電源を生やしている
    • 犯人はヤス
    • 施工するとき、リレーを買ってバッ直にしようとしたけど面倒になってやめた
    • アクセサリの配線がうっかり切れないように、申し訳程度にヒューズを入れている
  • フロントフェンダー固定ネジ1本欠品

あれ、、、?思ったより重症??

このコンディションを考えるとヤフオクで4万ちょいだったのはちょい高かった気がしてきました。まぁ、親切なおっちゃんが群馬だか埼玉だかちょっと遠くから軽に乗っけて運んできてくれたし(礼金は払ったけど業者より全然安い)、なんかいろいろ教えてくれたし、定期的に軽い修理が生えて楽しいし、元は十分取っているからいいか。

で、楽しく乗ってはいたけども、フロントサスがダメになっているせいでちょっとした段差でもガタガタ言って不快なので、修理することに。ふとヤフオクを開くとCA41A用の実働車外しのフロントフォーク一式が1kで出品されているではありませんか。

f:id:kat0h:20260303215731j:image
フォークの構造を知らないので、Let'sの置いてある実家に戻ってフォークを外してバラしてOHして、、、なんてことをするのは現実的ではないと判断したので、出品されているものを落札してOHしてから実家に持ち帰り交換することにしました。

これが届いた時の状態。一部に軽くサビが浮いており、グリスが漏れた跡もありますが、歪みや酷いキズもなく悪くない状態でした。

f:id:kat0h:20260303215747j:image
とりあえず、全体をバラしてグリスを新しいものに入れ替えようと思いましたが、どうもこの手のフォークはスナップリングで固定されているらしく、当然のようにスナップリングプライヤーは自宅にありません。Amazonで中華の安物を注文しましたが待ち切れず近所の島忠でプライヤーを購入してしまいました。また、フォークブーツも当然欠品しているので、Amazonで購入。この時点でフォークの購入額を超えています。

ちなみにスナップリングの穴径は1.2mmでした。サスペンションに体重を掛けて縮めた状態でスズランテープで締め、スナップリングを外しフォークを分解します。原付の部品は人力でもなんとかなるのが良いですね。

f:id:kat0h:20260303215804j:imagef:id:kat0h:20260303215812j:image
サビの浮いたフォークの外装はダイソーで購入したラッカーと共に大学に持参し、夜のサークル棟の裏でコソコソ雑に塗装しました。ドライヤーで塗装を乾燥させる雑な施工でしたが、それなりに綺麗になり満足です。

f:id:kat0h:20260303215821j:image

ロアアームには手元にあったリチウムグリースを雑に塗り込み、後輩の力を借りながら再度組み直してOH完了です。

f:id:kat0h:20260303215829j:image

 三月の後半にでも実家に持ち帰り組付ける予定でしたが、折角綺麗になったフォークが手元にあるとどうしても我慢できず交換のために帰省することにしました。
バイクにフォークを積み込み高速で長野まで、高速代3.5k+ガソリン代1.1k(回して走ってたらありえん燃費が落ちた)ほど。高い、、、快適だけど、、、

f:id:kat0h:20260303215839j:imagef:id:kat0h:20260303215844j:image

交換の作業がどれほどスムーズに進むか心配でしたが、比較スムーズに終わりました。作業手順は大体次の通り。

  1. ジャッキアップ(そこらの角材の上に持ち上げて載せるだけ)
  2. 前面カウルの取り外し
  3. ハンドル固定用ネジx2の取り外し
  4. タイヤ固定用のシャフトの取り外し (12mmと14mm(だったかな)のレンチでいける)
  5. フォーク裏のケーブルガイドの取り外し
  6. フロントフェンダーの取り外し
  7. フォーク上部のネジの取り外し
  8. フォークを下方向に抜いて取り外し

こんなところ。調整が必要な箇所もほぼなく、自転車よりも簡単かもしれないですね。

f:id:kat0h:20260303215903j:image
フォークを外している間、ハンドル周りがケーブルだけで宙に浮いてしまうので精神衛生的に良くない。そこはなんとか頑張ってください。妹に助けを求めたら拒否されました。

この時点ではまだフォークブーツが届いていなかったため、とりあえずゴミが入らないようにクレラップを巻きつけて試走。

うーん?ちょっと良くなった?明らかにガタガタした振動は減ったので良かったかも。それに、フロントが少しだけちゃんと整備されている見た目になったので満足です。

そして、今日フォークブーツが届いていたので、取り付けました。やりにくいとは聞いていたので、ブーツを予め熱湯に漬けてゴムをやわらかくしてからなんとか。綺麗になって満足。アクスルシャフトはなんとなくジャッキから降ろしてから締めました。

f:id:kat0h:20260303220515j:imagef:id:kat0h:20260303220515j:image

これで、フロント周りは当分触らずに済みそうです。

オチ

 

ArchLinuxにプリンタの公式ドライバを導入する

linuxを導入したパソコンから印刷をする際にCUPSを使いますが、IPPプリンタの定義ファイルとしてGeneric Printerを選択するとうまく印刷できないことがあります。

大学のサークルの部室で利用しているCanonのMF273DWの旧型機は問題なく印刷できますが、自宅のLBP122は接続こそできるもののプリントできませんでした。

Canonからdebもしくはrpm形式のパッケージが提供されていますが、pacmanでは直接インストールできません。

そこで、debtapを用いてdebパッケージを変換してコンピュータにインストールしたところ、印刷できるようになったので、過程を記録します。

前提

インストールしたパッケージは下記のドライバです。CUPS向けのPPDファイルやフィルターのコマンド群が含まれているようです。

LIPSLX/ CARPS2 Printer Driver for Linux Ver.6.20(32bit & 64bit)|キヤノン

また、debtapをAURからインストールしました。

GitHub - helixarch/debtap: A script for converting .deb packages into Arch Linux packages, focused on accuracy

手順

パッケージの変換とインストール自体は簡単です。

debtap パッケージ名.deb
sudo pacman -U xxx.zst

途中でファイルを編集するか問われるので、任意のエディタで編集してください。

Archlinuxとdebianでパッケージ名が異なるパッケージに依存していることがあります。このようなものに関しては正しい名前に変更しておきましょう。

また、debtapは稀にvalidではないシェルスクリプトを吐き出します。そのような場合は手作業で修正します。

作成したパッケージをpacmanでインストールすれば晴れてプリンターが追加できるようになるはずです。

 

同様の手順では、BrotherのHL-L2375DWも動作するようになりました。

原付のナンバープレートを変えてみた

ことのあらまし

出力を制限した125cc以下の原付自転車を一種原付として扱う新基準原付制度が始まりました。

これに伴い、調布市ご当地ナンバーがリニューアルされました。 新しいナンバーのキリ番の抽選に応募したところうっかり当選してしまったので、ナンバーを交換することになりました。

準備

用意するものは以下の通りです。

  • 現在のナンバー
  • 標識交付証明書

また、自賠責のシールはあらかじめ剥しておくとよいでしょう。このシールがないと公道を走れません。

新ナンバー受け取り

市役所に行き、ナンバーが欲しいです!と言うと、手続きをしてくれます。 ただし、ナンバーを変更するという動作は規定されていないので、一度現在の車両を廃車してすぐに登録することになります。

新しいナンバー・廃車申告受付書・標識交付証明書を受けとれば手続きは終わりです。

自賠責の車両入れ替え

自賠責保険(強制保険)の車両を入れ替えます。下記の書類を手元に用意して、Webから手続きを行います。

手続きはone-jibaiシステムから行います。 one-jibaiのアカウントがない場合は登録しましょう。 私は既に自賠責の住所書き替えをしていたため、アカウントがありました。

「契約内容の変更・解約・訂正手続き、証明書の再交付手続き 」をします

今回はバイクのナンバープレートの変更手続きになるので、「自動車(バイク)のナンバーレートが変わった」にチェックを入れます。 ステッカーの再交付を押すと、すぐに手続きが終わらない可能性があったため、今回は再交付はしないことにしました。

証明書番号はケースセンシティブなので注意しましょう(一敗)

「異動・解約(解除)日」は標識交付証明書の交付された日とします。

ナンバープレートの情報は間違いやすいポイントでした。

【自賠責保険・One-JIBAI】原付のナンバープレートの入力方法が分かりません。どのように入力した | よくあるご質問(FAQ) | 東京海上日動火災保険

原付自転車の場合は、入力フォームに注意して書き込む必要があります。詳細は上記ページを参照してください。

必要な書類の画像をアップロードすれば手続きは完了です。 証明書番号は変わらないはずなので、次は任意保険の契約の修正をしましょう。

任意保険の契約変更

私は国民共済で保険を契約しているので、コープのページで更新します。

こちらについては標識交付証明書の画像をアップロードするだけなので簡単でした。

おわりに

これで晴れて「調布市 K ・・・?」のナンバーを手に入れました。 もう悪いことはできません。

2025/06/11

自転車のチューブを交換
前にいい加減に前輪タイヤのチューブを交換したら、リムテープがズレてしまってチューブが裂けてしまった。
仕方ないので、もう一度チューブを交換した。
リムテープに変な癖がついてしまっていたが、ヒートガンで炙ったところちょうどよくなった。
これでもうパンクの心配はないはず

 

ThinkPadのヒンジを調節
使っているうちにヒンジがだんだんとゆるんでしまってきていたので、分解して調節した。
上画面をバラしてネジを小さいレンチとかで締めればOK。


パーサージェネレータがActionを指定できるように

 

工研新入生講習

 

RubyKaigi2025参加記 【学生支援 by pixiv】

ピクシブ株式会社様の学生支援企画でRubyKaigi2025に参加しました。

この記事では、自分が特に気になったセッションについて復習を兼ねつつ紹介します。

私の理解が間違っていたらごめんなさい。訂正・補足などあればコメントやTwitter(@kat0h)で教えてくださると幸いです。

inside.pixiv.blog

自己紹介

day-n

大学でコミッタの斎藤さんと集まり、昨年のRubyKaigiのセッションを観る会をしました。

私は言語処理系が好きなので、RubyKaigiではその周辺を勉強したいなと考えていました。 Ruby本体のセッションの中でも、特にパーサーの話は事前知識がないとついていけないなと感じたので、私のリクエストでパーサーの発表を(解説してもらいながら)見ました。

下記は見たセッションの一覧です。

rubykaigi.org

rubykaigi.org

rubykaigi.org

特に金子さんの発表のインパクトがすごかったです。30分の発表だったのですが、あまりにも話すのが早いかつ濃厚で、途中でとめつつああでもないこうでもないと見ていたら2時間が経ってしまいました。まじかよ

LR(1)/LALR(1)/IELR(1)/PSLR(1)などの関係をある程度整理してから会場に行けたのはよかったです。

day0

水曜日の夜に自宅のある調布から羽田を経由して飛行機で松山に行きました。ANAの飛行機に乗るのは幼稚園以来。孤独のグルメが放送されていました。
なんとか窓側席(非常席座席ですが)を確保したので、外の景色を眺めながら来ました。

松山には21時ごろに到着。お昼ならRubyKaigiの運営さんがチャーターしたバスがあったらしいが、当然夜にあるわけもなく空港の外に停まっていたリムジンバスに乗車。 実のところ、この時点で泊まるホテルの場所を知らなかったので必死に調べながらバスに乗っていました。結局途中の停留所で降りればホテルに行けることがわかったので、新聞社の前で降りて1kmほど歩いてホテルに到着。

0日目の夜はコンビニ飯かなぁと考えていたのですが、SmartHRさんのdrinkupを終えた斎藤さんとちーすけさんにお誘いいただき一緒にご飯をいただきました。 毎度お二方にはめちゃめちゃお世話になっています。

tech.smarthr.jp

大街道のアーケードにRubyKaigiの横断幕を見つけたりもしました。

そんなこんなでday0は日付が変わる頃に就寝。

day1

朝7時頃に起床。朝食付きの部屋を取ってくださってたので、朝ごはんを食べに行きました。 家から大学まで5分の生活に慣れきってしまっていたので、けっこうきついです。 夜まで集中してセッションを聴き通すためにがんばってご飯を食べました。

会場の愛媛県文化会館まではホテルから徒歩で20分くらいでした。実は路面電車にのればもう少し時間を短縮できたらしいのですが、地理が頭に入っておらず乗れませんでした。

Ruby Taught Me About Encoding Under the Hood (ima1zumiさん)

speakerdeck.com

文字コードと人生の話でした。

👨‍👩‍👧‍👧←この絵文字をirbに食わせたところ、irbがクラッシュしたという出来事をきっかけにコミッタにまで就任したそうです。尊敬しかない。

私自身も、高校の頃はVimにパッチを送るなどちょいちょいOSSにかかわってはいたのですが、継続することがなかなかできていませんでした。

「のめり込むようになってしまいました」という発言心に残っています。本当に楽しそうに発表されていてとてもよかったです。

Make Parsers Compatible Using Automata Learning (makenowjustさん)

個人的にたのしみにしていたセッションその1

speakerdeck.com

現在のCRubyのデフォルトのパーサーであるPrismと、Lramaで生成されるparse.yによるパーサーの挙動の違いを形式的に検証しようという発表です。

2つの異なるパーサーPlとPpが同じ挙動をするかは、パーサーは記号列を入力に取るオートマトンと考えると、L(Pl)=L(Pp)であることを示せばよいことになります。(発表ではL(Pl⊕Po)=∅かどうかを検証していました)

DFA同士が等価かどうかはそれぞれを最小化することで判定できると思うのですが、プッシュダウンオートマトンだとまた違うのかも、もしくはXORを取れば反例の入力文字列を(比較的)容易に生成できるという事情もあるのかもしれない)

2025/05/06追記
金子さんより、プッシュダウンオートマトンの等価判定についての補足をいただきました。

そもそも発表で扱っていたのはVisibly Pushdown Automataだったので、そもそも違うものでした。

なぜVPAにしたのか(うっかり聞き逃してしまったんだと思います)気になります。発表動画が公開されたら改めてみてみます。

追記終わり

2025/05/15 Pixivのアフターイベントで追加の情報をお聞きしました。

VPAを使ったのは、L*アルゴリズムが適用できる中では一番強いオートマトンだったから

オートマトン同士の比較なら普通に比較しても良いけど(別にandだろうが=だろうがxorだろうがやれることは同じ)、xorなら反例を生成しやすいというのはメリットではあるとのことでした。

追記終わり

Lramaの生成するパーサーに関しては、parse.yを見ればどのような状態集合と遷移規則を持つオートマトンができるかがわかります。

しかし、Prismパーサーは手書きの再帰下降パーサー(prattパーサー)であり、レキサーを内包します。 (下に示した4つ目の記事によるとRubyの文法は文脈依存文法らしいのですが、この文脈の解析をレキサーに投げることでparse.yの文法はLALR(1)に収まっています) ここからパーサーのオートマトンを生成することはかなりの困難を抱えると予想できるはずです。

そこで、この発表では入力と受理するかどうかしかわからないブラックボックスオートマトンであるLramaとPrismに対してオートマトン学習(L*アルゴリズム)という手法を利用することで互換性を検証したそうです。

私は昨年度大学で形式言語理論の講義を受けました。現代のプログラミングがこの理論の上に成り立っているというのは言わずもがな、、というのはわかるのですが、ここまで応用的に利用できるというのは非常に驚きました。

L*アルゴリズムによるオートマトン学習でパーサーのオートマトンを推測するには、O(kn2) (kは|Σ|、nは状態数)のコストがかかるそうで、Ruby全体の文法を対象に検証するのは現実的でないそうです。

実際、発表でもオートマトン学習に利用するアルファベットはΣ={"a", :, (, )}に限定していました。こうでもしないと計算量が大きすぎるようで、prism全部のオートマトンを生成するといったことは難しそうです。(アルゴリズムが対応できる言語クラスにRubyが属さないので、一部だけを対象にする必要があるという事情もあるはず)

この発表を聞いて仕様書の気持ちになれるプロだけが発見できるものだった互換バグが、ついに誰でも見つけられるようになったのか!!とワクワクしました。

後にお聞きしたのですが、入力にするアルファベットの選定はかなり大変だったそうで、どんな文法ならバグりそうかな〜などの見立てを立てて入力を考えるのはやはりプロしかできないようです。無念....

まったくついていけなかったのですが、自分がいま大学でしている勉強は役に立つんだという実感が得られてとても良かったです。

L*について説明してみる | makenowjust-labs/blog
Operator-precedence parser - Wikipedia
Prism:エラートレラントな、まったく新しいRubyパーサ | gihyo.jp
Rubyパーサーを一新するprism(旧YARP)プロジェクトの全容と将来(翻訳)|TechRacho by BPS株式会社

(Continuation is to be continued)

個人的に聞きたかったのですが、被っていて聞けなかったセッションです。
先日、自作にSchemeの(超小さいサブセットの)インタプリタにcall/ccを実装してから、call/ccという非常に強力な言語機能に心を奪われていました。

発表スライドが公開されていることをydah_さんに教えていただいたので、後で読みたいと思っています。動画の公開が楽しみです。

speakerdeck.com

昼ごはん

お昼ごはんはPixivさんとSMSさんの学生支援企画で来た学生であつまって鯛めしをご馳走になりました。

午前聞いたセッションの感想を話し合ったり、いまやっていることの話を聞いたり楽しい時間を過ごすことができました。SMSさんの学生支援で来た方とは初対面だったので、ゆっくりお話をする機会をいただけて大変ありがたかったです。

愛媛には、炊き込みご飯風の松山鯛めしと刺し身と卵黄を一緒にいただく宇和島鯛めしがあるそうです。今回伺ったお店では、両方の鯛めしを食べ比べることができました。

Ruby's Line Breaks

speakerdeck.com

個人的にたのしみにしていたセッションその2

Rubyの複雑怪奇な改行の仕様を明らかにしようという発表です。

Rubyのプログラミムにはおおまかに下記のような改行に関する規則があります。

スライドでは、このルールの(よく知られている)例外をいくつか解説していました。
しかし、本当にこれは十分な例外の集合なのでしょうか。。。?という疑問がでてきます。

Rubyの文法はPrismもしくは、parse.yでパースされているはずなので、この例外を探すのはパーサーの実装から形式的に探索できそうです。

今回の発表では、Rubyのparse.yを解析することでこのような例外を見つけ出す方法を提案していました。

そもそも、なぜRubyのparse.yというのはここまで恐れられる存在なのでしょうか。

前提として、多くの古典的なプログラミング言語はその構文解析器にyacc/lexやbison/flexから生成されたパーサーを使っています。これらが受理する構文は多少の差があれども、大抵はLR(1)(=CFG)やLALR(1)の文法に収まっているのが普通です。

しかし、多くのプログラミング言語の構文規則はCFG(文脈自由文法)の中に収まっていないことがあります。パーサーはCFGを受理できる能力しか持っていないわけなので、CFGからはみ出た規則はどうやって処理されるかというとレキサーで吸収されているようです。(lex_stateの話ですね)

つまり、yylex関数はRubyがCFGに収まるようにがんばる関数であるということで、複雑なのも頷けます。

改行に関しても、レキサーは文脈に応じて返す結果を出し分けています。

文法的に改行可能なところ(終わっている式の後など)なところに来た改行文字列は'\n'の終端記号として返し、逆にまだ式の途中にいることがわかる(1+ \n 2)のような状態では改行を読み飛ばします。

レキサーとパーサーの結合は疎にできているので、それぞれが個別に解析中の状態を保持します。

このような非常に複雑な状態を整理して理解可能にするために、発表ではパーサーとレキサーオートマトンを合成するということをしていました。
ここはきちんと理解できていないのですが、Lramaの文法を拡張してlexerの状態を一緒に管理できるようにしたそうです。

こうして、レキサーは改行を読み飛ばす状態に入っているのにパーサーは還元のために改行文字が入ることを想定している(lookaheadsetに\nがいる)状態や、逆にシフトのために改行文字を受け付けるのにレキサーが\nを読み飛ばす状態などを発見できたそうです。

makenowjustさんの発表でも感じたのですが、カオスに立ち向かうために理論を活用して、成果を上げていることにとても感動しました。自分がまだまだまったくコンピュータを知らないことを痛感しましたが、大学で勉強したことを上手に現実に持ち込むとこんなにも楽しいことができるのかとわかりました。

30分の発表だったのですが、面白すぎて体感では15分くらいで終わってしまったような気がします。

本屋さん

ホワイエ二階の一角で本屋さんが開催されていました。
1日目はmameさんの「型システムのしくみ」を購入しました。ちょうどmameさんが近くにいて、直筆サイン(!)を頂いてしまいました!超嬉しい!!

早速実行....

SyntaxError!!

プログラムの写し間違いでした。

下2行はコメントなんだろうな...とみせかけて!で文字列を閉じているという、ミスリーディングなコードでした。 サインまでQuine...恐ろしい...

TRICK 2025: Episode I

github.com

私がRubyを使い始めたきっかけはmameさんの書いたQuineでした。2022年のTRICKは高校の帰り道に電車で見ていました。今年のRubyKaigiでは会場で見ることができて感無量です。

できたらTrickに作品を応募したかったのですが、今の私の技術力・アイデアではできませんでした。 どの作品も、クリエイティブかつ高い技術で実装されていて尊敬です。

omoikaneさんのだるまのコードは、本当に仕組みがわからなくて怖かったです。解説markdownアスキーアート生成用のHTMLジェネレータが記載されていたのですが、あれを見る限り職人の手作業でコードが記述されているような気がします。何を食ったらあんな芸術的なコードが書けるのでしょう....

ところで、、Episode 1というのは何なんでしょう...

day2

Dissecting and Reconstructing Ruby Syntactic Structures

個人的にたのしみにしていたセッションその3

speakerdeck.com

Rubyの文法の全体像を把握しつつ、parse.yをより良くしようという発表でした。

いいなと思ったのが、Perl/PHP/Rubyの構文(特に式まわり)の特徴をつかむために、lramaへの入力から構文図式を生成するツールを作ったという話でした。LTで詳しく話されていました。全体像をなんとなくつかむのにはとても便利そうです。

前にawkのパーサーを書いたときに感じたのですが、やはり式の構文を把握するというのはかなり大変な作業だと思います。Rubyも例にもれず、引数にかけるargとprimaryが分かれているなど他の部分と衝突しないために構文規則が分かれています。

理解が難しい文法の例として、カンマで区切られたリストのような規則をBNFで表現しようとすると、下のようになります。

rule1 := rule2
      | rule2 ',' rule1
rule2 := 'e'

自然言語で表現すれば「カンマ区切りのe」と表現できるのに、BNFがプリミティブな記法を持たないためにこのような記述をしなければなりません。 ただでさえ難しい文法の読解をより難しくしてしまいそうです。

上の例は本当に簡単な文法ですが、それなりに長く複雑な文法のBNFを読む際、再帰的な記述から構造の本質をサッと読み取るのは大変です。

もちろん、CFGを処理する機械が扱えるのは再帰的な構造なので、「n個の連続」のような記法は糖衣構文の一種になりますが、このような記述が書けるというのはすごく便利だと思いました。

また、同じ形・意味を持っているが違う構文規則の場所で記述されている規則をジェネリクスのようにまとめて扱えるようにするというアイデアは面白いなと感じました。

parse.yが整理されてRubyの文法の本質的な難しさに集中できるようになる日が楽しみです。

ZJIT: Building a Next Generation Ruby JIT

Rubyの新しいJITの紹介のセッションです。

ShopifyがYJITを作った結局としてパフォーマンスが頭打ちになってしまったので、先20年のメンテナンスを見込んで新しく設計をやり直したという話でした。

これまでのYJITはYARVバイトコードインタプリタをベースにJITを組んでいたのに対して、ZJITは教科書的な設計のmethod-basedなJITだそうです。Prismのようなものを見ていると、Shopifyの方がこのような昔ながらの設計をすることに驚きがありました。

Ruby が YJIT でなんで速くなるのか? Lazy Basic Block Versioning をサクッと理解してみた - estie inside blog

The Implementations of Advanced LR Parser Algorithm

個人的にたのしみにしていたセッションその4

speakerdeck.com

Lramaに新しく実装したIELRという状態表生成アルゴリズムの紹介です。

Lramaの最終的な目標として、parse.yを読みやすくすることがありました。そのために注目しているのがPSLR(1)という方法で、これを使うとスキャナー(レキサー)を使わずにパースができるそうです。(厳密な定義をまだ理解できていないです,,,)Rubyにこれを導入する嬉しさとして、パーサーとレキサー構文解析の状態を共有することで設計が簡潔になるとされています。

cf: speakerdeck.com

https://open.clemson.edu/cgi/viewcontent.cgi?article=1519&context=all_dissertations

PSLR(1)はIELR(1)の発展形として実装されているので、まずはIELR(1)を実装する必要があるということでLramaにIELR(1)を実装したそうです。

IELR(1)を考える前にLR(1)から考えてみることにします。

簡単な文法

例として、上のような文法からLR(1)(スライドではCanonical LRと表現されていました)の正準オートマトン(≒パーサーの状態)を求めてみると、状態数は22個になってしまいました。

規則が数個しかない文法ですら、こんなにも多くなってしまうのですからより複雑な文法だともっとひどいことになるのは容易に予想できます。

speakerdeck.com ↑LRでJSONパーサーを書いた結果状態数がえらいことになっている

そこで考え出されたのが、LR(1)項の核が共通していて先読み記号のみ異なる規則を一つにまとめてしまうLALR(1)です。 LALR(1)はLR(1)よりも弱いですが、follow集合をつかうSLR(1)と同じ状態数でSLR(1)よりも広い(十分に実用的な)文法をパースできるということで広く使われています。

LALR(1)は十分に広い範囲をパースできるのですが、状態数の削減の過程でMysterious Conflictという現象が発生してしまうことがあります。これは、本来一つにまとめるべきでない状態をまとめてしまうことで発生するそうで、このようなパターンを回避するというのがIELR(1)の基本的なアイデアになるそうです。

つまり、扱える文法の大きさ的には
LR(1) = IELR(1) ⊃ LALR(1) ⊃ SLR(1)
状態数的には
LR(1) > IELR(1) > LALR(1) = SLR(1)
になります。

www.gnu.org

いいことづくめな気もしますが、IELR(1)では状態の計算にかかるコストがかなり重くなってしまうほか、プログラムもそれなりに複雑になってしまうそうで、スライドの後半では実装の過程でのトラブルが紹介されました。

day3

本屋さん②

うちのSchemeインタプリタGCを実装したいので、ガーベジコレクションの本を買いました。大学に行けばあるのですが、手元に置いておきたかった。

また、inductorさんにeBPFをめっちゃ推されたのでeBPFの本も購入しました。

学生身分にとっては技術書を新本で買うのはかなりハードルが高いのですが、RubyKaigiに行ってとてもモチベーションが高くなっていたこともあり買ってしまいました。

Analyzing Ruby Code in IRB

drive.google.com

IRBがいかにして動作しているかという発表です。

IRBは入力途中(=Rubyに属していない言語)をいい感じに扱う必要があるということで、Prismのエラートレラント機能をうまく利用しているらしい。

私たちが使うときに、Rubyの書き味を失わないようにいい感じに調整してくれるIRBの偉大さと、むずかしさを目の当たりにしました。

day4

day4は大学の知人たちとレンタカーを借り、しまなみ海道にドライブに行きました。

飛行機が19時ごろの離陸ということもあり、少し時間に余裕がない状態でしたが、伯方の島まで上陸できて大満足です。

day5〜

RubyKaigiの影響で最近やっていることを紹介します。

パーサージェネレーターをつくってみている

RubyKaigiから帰ってきてからパーサージェネレーターを自分の手で作りたい気持ちになったので、教科書を読みつつ手を動かしてプログラムを書いてみました。

はじめはLR(0)項の閉包を求めるところから始め、徐々に関数を増やしたり、データ構造を見直したりしました。

まだ全くパーサーとして動きませんが、LR(1)項にたいしてClosureとgotoと正準集合の計算をできるようになったので、もうちょっとでそれっぽくなるんじゃないかなと思っています。

自分はこれまでRubyをQuineを書く用途にしか使ってこなかったのですが、Rubyの強力な文法と組み込み関数のおかげでとても楽しくプログラミングができています。

おもちゃみたいなものでも、一回実装に落として具体的なものを書けばLramaのような大きいシステムにも立ち向かえる知識がつくんじゃないかなとおもっています。

2025/05/20追記

LALR(1)パーサージェネレーター(ぽいもの)が完成しました

↑ドラゴンブックを買ってしまった(家計に大打撃)

追記終わり

議論するための言語をもちたい

Rubyistと会話をする中で、自分の言語能力の欠如を痛感しました。

自分の概念理解が浅いために、何度も同じ説明をしてもらってしまったり、せっかく教えて頂いたことをいまいち理解できないままにしてしまったことも多々ありました。 せっかく聞いたことを十分に自分のものにできないのはとても悔しいです。

言語は思考のための道具であるということをしっかりと心に刻み、これから勉強を続けていきたいとおもいました。

ネットワークで遊びたい

RubyKaigi NOCの活動を見て、ネットワークの構築にも興味を持ちました。

いまだにどうやってRubyKaigiのWifi網が実現されているか(特にNAT64周り)わかっていません。

自分もネットワークに詳しくなりたいなと思い、まずはということで自宅に少しだけネットワーク機器をそろえて遊び始めることにしました。 とりあえず、自宅から作業するときに大学のネットワークをうまく活用できるようにいろいろいじってみようかと思っています。

↑自宅に固定のIPv4アドレスを振ってもらったので、サークルの部員とIPsecでピアを張りました。

↑いまの自宅のネットワーク環境。(RTX1210+アクセスポイント+openwrt(VPN用))

Rubyのパーサーに翻弄されている

Rubyのパーサーをもっと知りたいと思って、いろいろ試した記録です。

→持っていそう?

変数があるかどうかでレキサーの結果が変わっている様子

→厳密にはCFGに収まっていなそう?

(ここで自分がRubyのパーサーがlexical feedbackをしているといっていますが、これは自分の勘違いだと思います。)

2025/05/06追記

lexical feedbackの定義によりますが、Rubyでもしてるそうです

追記終わり

RubyKaigiから帰ってきたあとの授業で、構文解析の話題が出てきました。ちょうどRubyKaigiで聞いてきたことも触れられていてちょっとうれしかったです。

来年のRubyKaigiどうする

次のRubyKaigiは函館で開催されるそうです。

来年もぜひ参加したいと思っています。次はもっと技術をつけて、成果を引っ提げて行きたいです。

さいごに

今回の参加費用を援助してくださったピクシブ株式会社様、私達がRubyKaigiを楽しめるように全力で支援してくださったPixivの皆さん、本当にありがとうございました!!

また、貴重な時間を割いて私と話してくださったスピーカー・コミッターの皆さん、Rubyistの皆さんありがとうございました!勉強したいことが増えてとても楽しいです。

Rubykaigiを運営してくださったスタッフの皆さん、スポンサー各社の方々、松山の方々、ありがとうございました!

またどこかでお会いしたら、どうぞよろしくお願いします。

参考文献

  • 湯浅太一著, 情報系教科書シリーズ第9巻 コンパイラ, 昭晃堂

2025/04/28

数日間の記録をつけ忘れた

 

ー、教習所で教習を受けた

二、工研でさいたままで軽くドライブに行った

三、愛媛みやげのみかんをもらった

四、工研部員間でIPSecVPNを貼った

五、RubyKaigiの参加記録をつけ始めた。

 

参加記録は現在7k字ほどになった。まだ全く書けていない。

 

 

2025/04/25

3年ぶりに日記を書くことにしました。
前の記事は2022-10-07。高校3年生のときです。

ちょうどこの頃が大学受験の真っ最中で、面接に行った頃だったと記憶しています。

VimとQuineを引っ提げて大学に行き、うっかり電通大に入学しました。
大学というのはとても楽しいもんで、あっという間に3年生です。

大方単位は取れているので、4年生への進級は確実でしょう。数値計算の授業さえ落とさなければ。
仮に留年をすると、その時点で100万の追加の費用負担が生じ、大学にとどまることができなくなります。




3年になってからは金曜が全休になり、他の日が全て1限から始まるようになりました。
よるにきっかり体力を消耗して寝れる生活に。

言語論の先生とALGOLに再帰関数導入された経緯を話していました。
ALGOL60の仕様策定段階では、どうも再帰関数というのは通常の関数と別のものとして定義しないと処理系を実装できないと考えられていたみたい。よって、再帰関数の実装には消極的だったんだけど、土壇場で無理くりこれを可能にする文言(16word)を入れたとか。
ただ、結局それがなくても再帰関数を実装できることがわかっちゃった。残念

あと、algolのcall-by-nameの話。引数が参照されるたびに評価されるやつ
algolはcall-by-valueとcall-by-nameの両方の評価戦略がつかえるからややこしい。実用法はきっとたくさんあるんだけど、多分何やるにしても大変だと思う。call-by-valueはきっと超強力な概念。call-with-current-continuationと似た雰囲気を感じる。

Pythonのリスト内包表記って、いつからかのバージョンでスコープを作るようになったらしい。あるコード片を実行してベンチマークを取るときは、関数にくるんだ状態とそうでない状態を別のものとして分ける必要がありそう。
トップレベルならグローバル変数で名前引きだけど、ローカルならindexで引くから速いとか、しょうもない理由で結果が変わってしまう。

ところで、Ruby Kaigi 2025でずっとパーサの話を考えていたこともあり、湯淺 太一先生のコンパイラでLR(1)構文解析のことを調べていた。junk0612さんから強力な資料を提示してくださったこともあり、LALR(1)完全に理解したというところまで持ってこれた気がする。パーサーを議論するために必要な言語をある程度会得したんじゃないか?
speakerdeck.com

というわけで、いったんLALR(1)パーサージェネレーターを書くことを目標にしてやってこうかなと思っている。