コログ

最近のこと。

これは生きたログだから,最近のことをかき殴ろうというわけだ。

● プログラム紀

始まる。
久しぶりに,プログラムを趣味でカタカタやる。

もっぱら

● flex & bison in C++

というやつだ。
flexとbisonを使って,簡単すぎるインタプリタぐらいまでは作れそうな感じに。

bison -> flex へのヘッダファイル提供。
実際には,bisonで言語ルールまで書いて%tokenや%typeで宣言した部分を,
後に flex で#includeして使うということのよう。

これには,

● これに

めっぽうお世話になりました。
動物の柄のこの本,学生時代から憧れの象徴。

実際には,2年前ぐらいか。秋ぐらいから寝床で読んでは
単語がわからずiphoneとかで調べる。

  • precedence:優先順位(計算機演算ではpriorityて言わないのかな)
  • arbitrary:任意の
  • adequate:十分な
  • punctuation:句読点(句読法か)
  • glue to:接着する
  • simultaneously:同時に
  • albeit:〜であるが。
    (p12. “This is a hack, albeit a very useful one, since most of the time it does the right thing.”)

いくつかは入試レベルな気もし。
albeitって,そういう意味で使うんだ。など。

● 下記は,去年の夏に書いてボツにしたブログから

−−−−−−
● 学生のとき(1994〜2000年ぐらい)

大学の授業でBNF記法というのを学んだわけだが、まあ

→ 学べてなかった

単位はもらえたんだっけ。という。
bisonでは、言語仕様をBNF風に書かねばならなかったはず。

● 戸塚時代(2002年〜2007年ぐらい)

よーしいっちょう、flexでも勉強して、新種のプログラミング言語でも発明してやりますかぁ〜
と意気込み、再三挫折。

ギリflexまでは分かる。
けどbisonで何度やってもどうやっても僕の書いたBNFの言語仕様が

● ambiguous grammar

ていうエラーになる。
訳すと「曖昧な文法」。何が曖昧じゃい。曖昧な日本の私のプログラム言語の仕様。

僕にはもう、bisonを使う才能とか、生きている価値とか、死なない権利とか、笑う勇気とか、

● 何にもないに違いない

と咆哮したり呻いたりして畳の目に逆らって爪を立てたり、足の裏で敷居をゴシゴシしたりしては、とにかく、諦めていた訳だ。
−−−−−−

● という

存外に元気な感じでやってたわけだ。
やがて分かりかける。

● 飯も自炊し

再び去年の盆に書いてボツにしたブログから引用する。

−−−−−−
● で

何に感動したかというと、この『flex&bison』の「計算式を入力すると、加減乗除を優先順位を守って計算する」という
サンプルプログラムをつくる中での p.14 だ。

またしばらくすると、仕事で頭が一杯になって、何を理解したのか忘れると思うので、備忘録として残す。

Ambiguous Grammars: Not Quite
The reader may be wondering at this point whether the grammar in Example 1-5 is needlessly complicated. Why not just write this?
(読者はExample 1-5が不必要に複雑だと思っているかも知れない。こう書いてはだめかと。)

exp: exp ADD exp
   | exp SUB exp
   | exp MUL exp
   | exp DIV exp
   | ABS exp
   | NUMBER

そうそう、まさにそう。↑みたく書いちゃなんでダメなんだって十年来わからなかった。
この辺、わくわくしながら読んだ。

ちなみに「Example 1-5」というのは、bisonへ渡す言語仕様を書いたもので p.11 にはこうある。

Bison’s Rule Input Language
Bison rules are basically BNF, with the punctuation simplified a little to make them easier to type. Example 1-5 shows the bison code, including the BNF, for the first version of our calculator.
(bisonに渡すコードは基本的にBNFだが、容易に書けるよう記法を少し簡単にしている。Example 1-5 に計算機の一番最初のバージョンのためのbison用のコード(BNFを含む)を示す。)
Example 1-5 Simple calculator fb1-5.y

 <前略>

calclist: /* nothing */
  | calclist exp EOL { printf("= %d\n", $1); }
  ;

exp: factor
  | exp ADD factor { && = $1 + $3; }
  | exp SUB factor { && = $1 - $3; }
  ;

factor: term
  | factor MUL term { $$ = $1 * $3; }
  | factor DIV term { $$ = $1 / $3; }
  ;

term: NUMBER
  | ABS term { $$ = $2 >= 0? $2 : -$2; }
 ;

<後略>

そうコレなのだ。僕が戸塚時代にメロメロになったやつ。
よく入門書なんかに書いてあるやつだ。

何でこんなに分けて、わざわざ複雑に書かねばならんのだと。謎だった。

p.14でLevine先生が言う「The reader wondering at the point」こそ僕だ。

そしたらそのp.14にはこう続く。

There are two answers: precedence and ambiguity. The separate symbols for term, factor, and exp tell bison to handle ABS, then MUL and DIV, and then ADD and SUB.
(答えは2つある。優先順位と曖昧さだ。termとfactorとexpを分けて書くことで、bisonにまずABSを、その次にMULとDIVを、そしてその次にADDとSUBを処理するよう指示している。)

興奮して音読していた。
そういうことだったんだ。今までこの世のどこにもなかった答えが初めて身に染み入る。ッアー!
−−−−−−

● 何やら

感動している。
スピッツのメドレーをyoutubeで流しながら,暑い日,来る日も来る日も

● 新築の

家の中で猫と僕だけ住んでる状況。
その中で,ずっとプログラム三昧。何度かラム肉食って赤ワイン飲みまくって吐く。

● 分かったことは

C++でflex, bisonを利用することは可能ということと,
ヘッダファイルで

#undef YY_DECL
#define YY_DECL \
yy::Parser::token_type \
Scanner::scan(yy::Parser::semantic_type* yylval, \
			  yy::Parser::location_type* yylloc, \
			  ParseDriver& driver)

とかやったり,かなりトリッキーだということと。

Parser.y内で,


%{
#include "ParseDriver.hpp"

//yylex()のオーバーロード
yy::Parser::token_type
yylex(
yy::Parser::semantic_type* yylval,
yy::Parser::location_type* yylloc,
ParseDriver& driver) {
	return driver.scanner->scan(yylval, yylloc, driver);
}

// parser's error routine <- it's need to be implemented by us
void
yy::Parser::error(
const yy::Parser::location_type& l,
const std::string& m) {
	driver.error(l, m);
}
%}

なんていう,なかなか香ばしいことを書く必要。

● なんか

もともと flex, bison が広域変数使いまくったり,
#ifndefや#defineつかって,凄いことになってたりする中,

● flex, bison in C++も

C++のクラスを使う上で,かなり凄いことになってる。ということのよう。
勉強したのは下記。

  • Blog Alpha Networkingめっちゃお世話になりました。GW前〜GW中@ハトヤ。ずっと解読してました。言ったら実際に手で打って写してました。
  • bison-test@GitHub日本人の方のソース。めっっっっっちゃ分かりやすかったっす。ありがたい。
  • flatB-Compiler-and-Interpreter@GitHubAST(Abstract Syntax Tree:抽象構文木)をC++で作ろうという場合の,B-flatというC言語ぽい言語の,(1)文法チェック(2)インタプリタ(3)コンパイラの例示。すげえ。
  • 10.1.4 C++ Parser InterfaceGNUか何かの,てほどき。bison側の。
  • Generating C++ scannersGNUか何か。flex側の。

やっと,コンパイルフリーなBison/Flexのtinyセットを作成できた。
コレを元に,ASTつくって逐次実行するサンプルができたら,

● やっと

1年以上ぶりにyoutubeのサイトを更新できそうだ。
今日はプログラム紀について。

● 次回は音楽編

そんで次は,最近の人生観について。
順次追記していく。