2007年10月11日
複雑な関数は上に置け!

最近はなかなか多忙でINできないので…
lslプログラムをSciTE上で作ってみたりしていました。
(SciTEは汎用プログラムエディターです…詳しくはココを)
INする時間がなくても、コンパイルが通るかどうかまではSciTEだけで作れますし。
で、だんだんプログラムが長くなってくると。コンパイルチェック時に
Parser stack depth exceeded
などという、エラーが出てしまう事が多くなりました。
このエラーの挙動がなんだかよくわからい感じで…
気持ち悪かったので調べてみました。
まずlslプログラムは複雑な状態になると…
…簡単に言うと150以上の階層ができてしまうとエラーになってしまうようです。
変数・関数の宣言はそれぞれ1階層増えたとみなされます。
うーん、簡単じゃないですね。
実は、自分もよくわかってません。が、なんとなくはわかりました。
ここで、エラーになる例を1つ
integer I01;
integer I02;
integer I03;
integer I04;
:
: 中略
:
integer I148;
integer I149;
integer I150;
default{
state_entry(){
}
}
このように変数を150個宣言すると、150個目でエラーになり、コンパイルが通りません。
まあ、こんなバカなプログラムは書かないでしょうが。
これは変数の宣言が関数の宣言になってもほぼ同じです。
関数の場合は(3つへって)147関数を宣言するとエラーになります。
次の例です。
F01(){}
F02(){}
F03(){}
F04(){}
:
: 中略
:
F131(){}
F132(){
if(TRUE){
if(TRUE){
if(TRUE){}
}
}
}
default{
state_entry(){
}
}最後の関数がこういう感じの内容の場合、ぐっと減って132個目の関数宣言でエラーになります。
(注:式の意味は滅茶苦茶です)
あと残り約15階層はどこでカウントされてるのか。
それは
if(TRUE){
if(TRUE){
if(TRUE){}
}
}の部分です。
しかし試しにこの行のifネストを1個減らしてみると
if(TRUE){
if(TRUE){
}
}エラーにはなりません。
合間に式を沢山はさみこんでも
F132(){
if(TRUE){
if(TRUE){
i++;
i++;
i++;
i++;
i++;
i++;
}
}
}エラーはでません。
関数宣言、for,if,whileなど、{}で囲む部分が増える箇所で
式の階層数がいくつかカウントしまうようで…
特にforが階層数を多く消費するようです。
つまりlslソースの後半に、ネストが激しい関数(if,for,whileなどが多く書いてある関数)があると
その行でParser stack depth exceeded =コンパイラがソースを解析中にスタックの限界の深さを超えてしまいましたなるエラーが出てしまう可能性が大きいわけです。
しかし、いったんネストが閉じられると
もとの階層数まで使用数が戻えいます。
その関数でエラーにならなければその後変数や関数宣言が続けられるわけです。
具体的には
さっきの例を
F131(){}
F132(){
if(TRUE){
if(TRUE){
if(TRUE){}
}
}
}↓
F132(){
if(TRUE){
if(TRUE){
if(TRUE){}
}
}
}
F131(){}と順序を逆にするだけで、エラーにならなくなります。
F31ではまだ使用階層数に余裕があるからです。
この結果から、タイトルにあるように
長いlslを記述する際は、複雑な関数をソースの上部に配置しろ
というテクニック?が導かれます。
同様に
長いlslを記述する際は、無駄な変数を宣言するな
長いlslを記述する際は、無駄な関数を宣言するな
というテクニック?も導かれますね。
1度しか使わないものでも、定数を宣言したり、意味ごとに関数にまとめるのは
scriptの見通しを良くするのに大事なことなのですが…
上記のテクを適用すると、とてもプログラムが汚くなります…。
なんだかなあ。
いや、そもそも
lslでソースが長くなるような複雑な処理は書くな
という事なのかもしれません!
トホホって感じですが。
記事書くのにつかれた。今日もSLで遊ばずに…寝ます。
lsl、ECMAscriptとかで実装しなおされてくれないかなあ。
この記事へのトラックバックURL
この記事へのコメント
ああ、そういえば実際にSL上にソースをコピペして動作を確認するのを忘れてました。
SciTEで表示されるメッセージは
Parser stack depth exceeded; SL will throw a syntax error here.
なので、同じだと思いますが、
ビューアもどんどんアップデートしてますしね。
どうなんだろう。
SciTEで表示されるメッセージは
Parser stack depth exceeded; SL will throw a syntax error here.
なので、同じだと思いますが、
ビューアもどんどんアップデートしてますしね。
どうなんだろう。
Posted by harayoki
at 2007年10月11日 04:48
at 2007年10月11日 04:48SciTE は日本語版もあったような。
んで、アスカさんがインストーラーの解説をしてたような。
それから、ウェブサイトに、lslを貼ってボタンを押すと、シンタクスエラーを検出してくれる所があったなぁ。
構想からコーディングだけ先に進めるのにとても便利だったよ。
んで、アスカさんがインストーラーの解説をしてたような。
それから、ウェブサイトに、lslを貼ってボタンを押すと、シンタクスエラーを検出してくれる所があったなぁ。
構想からコーディングだけ先に進めるのにとても便利だったよ。
Posted by VtWin at 2007年10月11日 07:23
VtWinさんこんにちは
SciTEに限らず、エディタの日本語版って個人的には必要ないですねえ
メニューがかわる程度ならSLと同じで実質あんまかわらないですし
でも敷居が下がるならいいのかな
ウェブサイトのやつってのはこれでしょうか
http://w-hat.com/lslint
SciTEでシンタックスチェックに使うのも同じlslintです
インストールしなくて使えるから確かにお手軽ですね
SciTEに限らず、エディタの日本語版って個人的には必要ないですねえ
メニューがかわる程度ならSLと同じで実質あんまかわらないですし
でも敷居が下がるならいいのかな
ウェブサイトのやつってのはこれでしょうか
http://w-hat.com/lslint
SciTEでシンタックスチェックに使うのも同じlslintです
インストールしなくて使えるから確かにお手軽ですね
Posted by harayoki
at 2007年10月11日 14:02
at 2007年10月11日 14:02はじめまして。
こことか
http://www.lslwiki.net/lslwiki/wakka.php?wakka=mono
ここの下の方
http://en.wikipedia.org/wiki/Linden_Scripting_Language
をみると、LSLはMONOベースに移行するかも、
と書いてあるように見えるんですが、
MONOはJScriptも一部サポートするようなので、
もしかしたらECMAscriptでコーディング出来る日がくるかもしれませんよ~。
こことか
http://www.lslwiki.net/lslwiki/wakka.php?wakka=mono
ここの下の方
http://en.wikipedia.org/wiki/Linden_Scripting_Language
をみると、LSLはMONOベースに移行するかも、
と書いてあるように見えるんですが、
MONOはJScriptも一部サポートするようなので、
もしかしたらECMAscriptでコーディング出来る日がくるかもしれませんよ~。
Posted by sabro
at 2007年10月11日 23:53
at 2007年10月11日 23:53sabroさんこんばんは
MONO…はよく分からないですが
今のlsl(バージョン2らしい)は、その場しのぎの仕様だらけなのと、配列の扱いが惨いので進化するならうれしいことです。
javaやC#みたいにガチガチになってほしくはないですが…。
ECMAscriptがいいってのは自分が使い慣れてるからっていうだけです。
作品作りは好きですが、本来プログラムは嫌いなのでw楽なのがいいなあと。
ruby/pythonとかでもいいかな。
#すぴりったん面白そうでイイデスネ!
MONO…はよく分からないですが
今のlsl(バージョン2らしい)は、その場しのぎの仕様だらけなのと、配列の扱いが惨いので進化するならうれしいことです。
javaやC#みたいにガチガチになってほしくはないですが…。
ECMAscriptがいいってのは自分が使い慣れてるからっていうだけです。
作品作りは好きですが、本来プログラムは嫌いなのでw楽なのがいいなあと。
ruby/pythonとかでもいいかな。
#すぴりったん面白そうでイイデスネ!
Posted by harayoki at 2007年10月13日 00:18
harayokiさんこんばんは
って自己レスなんですが。
>ああ、そういえば実際にSL上にソースをコピペして動作を確認するのを忘れてました。
この部分、メールでインワールドで試してみたところエラーにならないと報告いただきまして…
あーやっぱそうなのか、と思いつつ
自分でもテストしてみたところsyntaxエラーとなりました。
(試したのは150個のinteger型を宣言するヤツです。)
???なんですが
ビューアのバージョンやscriptの書き方、状況によっても結果がかわるのかもしれません。
lslIntのコンパイルチェックと純正のコンパイルチェックでは異なる部分もありそうですしね。
って自己レスなんですが。
>ああ、そういえば実際にSL上にソースをコピペして動作を確認するのを忘れてました。
この部分、メールでインワールドで試してみたところエラーにならないと報告いただきまして…
あーやっぱそうなのか、と思いつつ
自分でもテストしてみたところsyntaxエラーとなりました。
(試したのは150個のinteger型を宣言するヤツです。)
???なんですが
ビューアのバージョンやscriptの書き方、状況によっても結果がかわるのかもしれません。
lslIntのコンパイルチェックと純正のコンパイルチェックでは異なる部分もありそうですしね。
Posted by harayoki at 2007年10月13日 00:25


