みなさま今年もありがとうございました。個人的には卒業と入社があったりしてわりかし色々あった年でした。お疲れ様でした。
冬休みの自由研究(2)
昨日は大掃除をして疲れ果てたので The LEX & YACC Page や プログラミング言語を作る/yaccとlex などを読んでなるほど〜となっていた。 Lex の処理部分を改行しつつ書くと、正規表現にマッチしたら何かの処理をするという書き方が AWK に似ているということに気づいてひとりで納得したりした。
今日は JSON でパースの練習をするために、そのさきがけとしてまず JSON の字句解析をできる君を Lex で書いていた。 JSON の仕様は RFC8259 を斜め読みしている。 Strings の定義が以外と単純で、そうなのか、という感じだった。 Lex で書くのも楽。 Numbers は完全に忘れていたけど 1e3 みたいな表記もできたのだった。
unescaped [ !#-\[\]-] escaped \\["\\/bfnrt] escapedunicode \\u[0-9a-fA-F]{4} minus - plus \+ dot \. napiere [eE] digit19 [1-9] digit [0-9] %% \{ { printf("L_CBR\n"); } \} { printf("R_CBR\n"); } \[ { printf("L_SBR\n"); } \] { printf("R_SBR\n"); } : { printf("COLON\n"); } , { printf("COMMA\n"); } \"({unescaped}|{escaped}|{escapedunicode})*\" { printf("STRING\n"); } {minus}?(0|{digit19}{digit}*)({dot}{digit}+)?({napiere}({minus}|{plus})?{digit}+)? { printf("NUM\n"); } true { printf("V_TRUE\n"); } false { printf("V_FALSE\n"); } null { printf("V_NULL\n"); } " " { printf("WHITE\n"); } . { printf("CHAR\n"); }
余談だけど U+10FFFF は手元で上手く出せなくて U+10FFFF Unicode Character からコピペした (UTF8 では 0x10FFFF
なんて無理で 0xF4 0x8F 0xBF 0xBF
とかになるという話だった……)。
この lex ファイルを lex コマンドにかけて gcc コマンドにかけて、とやって得た実行ファイルを実行してやると、入力した JSON の文字を順番に読んでいって字句を解析する様子が見られる。改行を.
でマッチできていないのかよくわからないけど、 JSON ファイルに改行があるとそのまま出力にも改行で入ってしまう。壊れた JSON を渡すと、全く予期していないところで文字列が終わったりすることになるので、急に CHAR とかにフォールバック(?)して面白い。
$ cat in2.json { "クオートMAX": "\\s\\\"\\\"\\\"\\\\\"", "any array": [null, { "str": 0e2 }] } $ ./ajson1.out < in2.json L_CBR WHITE WHITE STRING COLON WHITE STRING COMMA WHITE WHITE STRING COLON WHITE L_SBR V_NULL COMMA WHITE L_CBR WHITE STRING COLON WHITE NUM WHITE R_CBR R_SBR R_CBR
あと、大学でやった実験のテキストの PDF を見つけてきて読みつつ、確かに定義部とかがあって定義しておけたのだった、とか、 Yacc のやることは Lex ができない括弧の対応とか入れ子になっていてとかそういう表現をカバーすることだったな、とか、 Lex と Yacc それぞれを実行して出てくる C言語のファイル lex.yy.c と y.tab.c をそのまま include して使うことができるのだった、とか色々思い出していた。
ちなみに Lex で頑張ってやった Strings や Numbers のつくりは、おそらく字句解析では部品だけにしておいて構文解析でカバーするという手もありそうで、そこは好きに境界を動かしてよさそう。今の感覚では正規表現でできるならできるだけやってしまったほうが BNF が単純になっていいのかな〜という感じ。 Yacc で定義すべき BNF のイメージはなんとなくついたし、そもそも RFC があるのでやはりそこに載っている通りにつくればできるはずなので、続きをやりたい。
(追記 201912302215) 改行は .
でマッチしないの仕様ですと教えてもらえたのと、そういえば RFC にちゃんと空白系はまとめてあったのでちゃんとやるとこうなった:
unescaped [ !#-\[\]-] escaped \\["\\/bfnrt] escapedunicode \\u[0-9a-fA-F]{4} minus - plus \+ dot \. napiere [eE] digit19 [1-9] digit [0-9] %% \{ { printf("L_CBR\n"); } \} { printf("R_CBR\n"); } \[ { printf("L_SBR\n"); } \] { printf("R_SBR\n"); } : { printf("COLON\n"); } , { printf("COMMA\n"); } \"({unescaped}|{escaped}|{escapedunicode})*\" { printf("STRING\n"); } {minus}?(0|{digit19}{digit}*)({dot}{digit}+)?({napiere}({minus}|{plus})?{digit}+)? { printf("NUM\n"); } true { printf("V_TRUE\n"); } false { printf("V_FALSE\n"); } null { printf("V_NULL\n"); } [ \t\n\r]+ { printf("WHITE\n"); } . { printf("CHAR\n"); }
$ ./ajson1.out < in2.json L_CBR WHITE STRING COLON WHITE STRING COMMA WHITE STRING COLON WHITE L_SBR V_NULL COMMA WHITE L_CBR WHITE STRING COLON WHITE NUM WHITE R_CBR R_SBR WHITE R_CBR WHITE
冬休みの自由研究始めた
雑談で構文解析面白いよ〜と教えてもらったのでやってみるかというので冬休みの自由研究している。大学で lex と yacc で自作言語を作る実験をやったことはあるものの、名前とコードの見た目以外全部忘れていて、手の付け方もわからなかったので、今日はひとまず lex から勉強し始めた。
lex というのは、 Plan 9 /sys/man/1/lex を見ると「generator of lexical analysis programs」 だそうで、日本語を探すと字句解析プログラム生成器という感じ。一緒に例が書いてあり、 lex だけでお試しできるいいやつだったのでお試しした。
ex1.lex
%% [A-Z] putchar(yytext[0]+'a'-'A'); [ ]+$ [ ]+ putchar(' ');
入力文字列を見つつ、上から順にパターンにマッチするか見ていって、マッチしたらそのときの処理をして次に進む、という流れ。例では、大文字アルファベットは1文字ずつ小文字にし、末尾空白は消し、空白が続いていたら1つにする、という意味。これは lex ファイルで、これを lex コマンドに渡すと C言語のプログラムを書いてくれる。そのプログラムを gcc コマンドでコンパイルして、実行しつつ文字列を入力すると、 lex ファイルに書いたとおりに文字列が出力される。
$ cat in1.txt abcABC 123 0A89FE44 A B C $ ./aex1.out < in1.txt abcabc 123 0a89fe44 a b c
普段こういうことをしたいときは、 cat in1.txt | perl -pe 's/ +$//g' | perl -pe 's/ +/ /g'
とかやっているので、ちゃんとコードとして書けるのは面白いな〜という感想。 C言語なので 'a'-'A'
で小文字にする、のような処理も書けて便利。何をするにも三日坊主になりがちなので続くかわからないけど、ゆっくりやっていけると楽しそう。
まさわだまわし
こんにちは、 id:hogashi です。 masawada Advent Calendar 2019 - Adventar の 8日目の記事です。昨日は id:mazco さんでした。
参加したいけど全然アイディア無いな……と思っていたんですが、 1日目の記事*1 で遊んだ途端に作りたくなって作りました。
まさわだまわしです。
ここで遊べます → https://hogashi.github.io/masawada-mawashi
masawada さんの 3D モデルを 6人同時にまわすことができます。
- 強く押すボタンをクリックで始まります
- マウスカーソルを動かすと、 6人の masawada さんがめいめいにまわります
- 最初は様々な方角を向いていると思うので、 6人全員に正面を向いてもらえる場所を探してください(ゲームの枠内にあるはずです)
- 40秒ほど経つと、この辺りで正面を向くよという丸が出る、おもてなし MAX な状態になるので、その中で探してみてください
- ピッタリ正面を向く場所を見つけることができると、全員で承認してくれます(そしてタイトルに戻ります)
スマートフォンでも(注意書きをokして突破すると)プレイ可能です。
お分かりかと思いますが、このゲームはモアイまわし (https://skt-products.com/contents/mawasy/index.html) のパロディです。モアイまわしは大好きなゲームのひとつです、皆様もぜひ遊んでみてください。
つかったもの
Unity (C#) と 3D モデルに入門しました。開発中の画面はだいたいいつも面白かったのでめっちゃ楽しかったです。
Unity と MMD くらいは少しだけさわったことがあったものの、 3D モデルを Unity でとか、マウス入力を取得するとか、とにかくわからなくてインターネットにある情報を拾いつつドキュメント (Unity - Scripting API) を見て、ひとまず書いては動かして確認していました。
やれるとよさそう
そもそも Unity をちゃんと勉強したい!! オブジェクトの移動とかも勘でとりあえずコード書いて動かして見て調整したりしていて、おそらくもっと便利であろう Unity を使いこなせていない。あと承認するとき 0.1秒ごとに 3D モデルをめっちゃ動かすようにしたら CPU を食いまくる感じで動作がもっさりしてしまったのも解決方法を知りたい。
そしてそれとは別にステージとか制限時間とか、ゲームっぽいつくりもできたい。
ちなみに
- 後ろに佇むロゴのフォントは Sonny Gothic です
- 日本語だけだとちょっと寂しかったのだった、慣れない手付きでクリスタ使って 20分くらいでつくったけどそれなりに気に入っています
- その他のフォントは「機械彫刻用標準書体フォント」(http://font.kim/) です
- これはめちゃめちゃおすすめで、何を書いても壁に貼ってありそうな注意書きっぽくなります
むすび
とっても勉強になりました。そして id:masawada さんには今年もとってもお世話になりました、来年もとってもよろしくお願いします。明日は id:equal_001 さんです。
本日の散歩
青山です。
I'm at 青山の庚申塔 in 港区, 東京都 https://t.co/kyUpVndD5v
— 越後湯沢 (@hogextend) 2019年11月29日
— 越後湯沢 (@hogextend) 2019年11月29日
— 越後湯沢 (@hogextend) 2019年11月29日
陸橋の下なのだけどどういう機構なのか、勘では振動をうまく吸収するとかな気がする pic.twitter.com/VhE3WJEvem
— 越後湯沢 (@hogextend) 2019年11月29日
本日の坂 nightsightスペシャル pic.twitter.com/0ghkUdMb0r
— 越後湯沢 (@hogextend) 2019年11月29日
— 越後湯沢 (@hogextend) 2019年11月29日
ちなみに撮ったのは Pixel 3a 。 Photos アプリで色あいなどをぐいぐい変えて遊んだりもしている。
ゴリゴリいじると絵みたいな感じになっていって面白い pic.twitter.com/UkLWIgEj5O
— 越後湯沢 (@hogextend) 2019年11月29日
■
巡音ルカをお迎えしたので少しずつ試してみている。 PC のストレージ容量が偶然めちゃめちゃ少なくて、英語をやってみたかったのでひとまず英語だけインストールした。英語を入れたらちゃんと読んでくれるのが楽しい。発音記号を扱えるのはとても助かるのだけど、それより細かく発音を変えたいときのやり方がわからない、理想的にはアとオの中間音をア寄りかオ寄りかのスライダーで調整したい。昔、 UTAU で重音テトに Simon & Garfunkel の Sound of Silence を(日本語発音をどうにか駆使して)歌ってもらうというのをやっていたので、その続きとしてルカでやり直している。ところで発音の数が少ない方がやることが少なくてすぐできて、フィンランド国歌の Maamme が完成した。