少し苦労したけれども Mac OS X の上で Google V8 を使って、構文解析器生成系の JS/CC を動かすことに成功した気がします。以下は自分のためのメモも兼ねた簡単な説明です。
* 問題の概要
そもそもの問題は JS/CC は Windows 用に開発されたようで、Windows と UNIX のコマンド行引数の扱いの微妙な違いがあるらいいということです。JS/CC を v8 で実行するときには以下のように起動します。
v8sh jscc.js -o mylang.js mylang.grammar
わたしは Windows を使わないのでよくわからないのですが、このとき v8sh の argv は UNIX では [ ‘v8sh’, ‘jscc.js’, ‘-o’, ‘mylang.js’, ‘mylang.grammar’ ] なのに対して、Windows では [ ‘jscc.js’, ‘-o’, ‘mylang.js’, ‘mylang.grammar’ ] なのではないでしょうか?JS/CC のソースを読むとそのように仮定しているように見えます。で、実際に上のように起動すると JS/CC は jscc.js 自身を文法定義ファイルと勘違いして、文法エラーをはいて異常終了します。
* 実際のビルド方法
ということで、引数を扱っているコードをちょこちょこ修正すればちゃんと動作するようになります。本当は Windows か否かを判定すればよいのですが JavaScript でそれをやる正しい方法を知らないので少し汚ない方法を取りました。
_boot_v8.js と main.js を修正します。
”_boot_v8.js” の 4736 行目あたりの
4735 var argv = get_arguments();
4736 for( var i = 0; i < argv.length; i++ )
4737 {
を
4735 var argv = get_arguments();
4736 for( var i = 1; i < argv.length; i++ )
4737 {
のように、i の初期値が 0 となっているところを 1 に変更します。
次もほとんど一緒なんですが ''main.js'' の 67 行目を変更します。
66 var argv = get_arguments();
67 for( var i = 0; i < argv.length; i++ )
68 {
を
66 var argv = get_arguments();
67 for( var i = 1; i < argv.length; i++ )
68 {
あとは ''make -f Makefile.v8'' でビルドできると思います。
* v8sh のビルド方法
JS/CC は v8 の標準的なシェルを若干拡張した v8sh のソースを含んでいます。これは複数のファイルのロードやファイルへの書き込みに対応させたようです。それはよいのですが、やはりコマンド行引数の扱いについて、前述と同様の問題があります。修正方法は以下の通りです。
// Bind the 'arguments' array
arguments = v8::Array::New(argc – 2);
for (int i = 2; i < argc; i++) {
という箇所を、以下のように変更します。
// Bind the 'arguments' array
arguments = v8::Array::New(argc – 1);
for (int i = 1; i < argc; i++) {
二箇所に出現する ''2'' を ''1'' で置き換えただけです。あとは普通に scons すれば v8sh ができます。この修正をしないと、v8sh を起動したときにメモリーが足りないというエラーが発生します。実際に確認したところ修正前の版の場合、UNIX では v8::Array::New(-1) という呼び出しになるのが原因です。
* お困りの方で
「このドキュメントだけでは無理!」な方には、Mac OS X で動く v8sh と jscc.js をさしあげますので、ご連絡下さい。
spidermonkey で試したら、今度は ”ReferenceError: parse_grammar is not defined” だそうです。v8 版ができたから、よしとする。つきあってられん。
JS/CC の開発者に、v8 での経験を伝えました。