SphereScriptには以下の構文の分類があり、構文解析器において最終的に大きな「スクリプト」が構成されます。
説明 | 例 | |
字句 | あらゆる「単語」 | 123 "メッセージ" x function set_pos while |
演算子 | 『字句』のうち、何らかの計算処理を行うもの | + * [ . |
括弧 | 『演算子』のうち、特殊な構文をもち、「『括弧』『式』『括弧』」の構文により演算が行われるもの | [ ] ( ) 注※{}は『文』の構成要素であり『演算子』には含まれない |
式 | 『字句』単体 もしくは 「『式』『演算子』『式』」の構文で表現されるもの もしくは 「『括弧』『式』『括弧』」の構文で表現されるもの もしくは 『関数』 | 5 x+3 sin(x+90) |
関数 | 『式』の一種で、「『関数型変数』『(括弧』『式』(,『式』)『)括弧』」で定義されるもの | get_pos(handle) |
左辺値 | 『式』のうち代入が可能なもの | x pos.z |
右辺値 | 『式』のうち『左辺値』以外の全て | x+100 sin(180) |
変数定義 | 『式』の一種で、「(ststic | extern)(const)『型宣言』『変数名』([要素数])(『=代入演算子』『初期値』)」で定義されるもの もしくは 『関数定義』 | get_pos(handle) |
関数定義 | 『式』の一種で、「(ststic | extern)(const)function (autorun)『(戻り値)型宣言』『関数型変数』『(括弧』(,『型宣言』『変数名』)『)括弧』(『文ブロック』)」で定義されるもの | get_pos(handle) |
文 | 「『式』;」により定義されるもの もしくは 『文ブロック』 もしくは 『if構文』 もしくは 『while構文』 もしくは 『for構文』 | |
文ブロック | 『文』のうち、「『{括弧』(0個以上の)『文』『}括弧』」により定義されるもの | {x=0;} {set_pos(org_pos);set_rot(otg_rot);break;} |
if構文 | 『文』のうち、「『if』『(括弧』『式』『)括弧』『文』(『else構文』)」により定義されるもの | |
else構文 | if構文の最後の要素で、 「『else』『文』」 もしくは 「『elseif』『(括弧』『式』『)括弧』『文』(『else構文』)」 により定義されるもの | |
while構文 | 『文』のうち、「『while』『(括弧』『(条件判断)式』『)括弧』『文』」により定義されるもの | |
for構文 | 『文』のうち、「『for』『(括弧』『(初期化)式』;『(条件判断)式』;『(繰り返し)式』『)括弧』『文』」により定義されるもの | |
ソースコード | 0以上の『文』により定義されるもの | |
スクリプト | 1以上の『ソースコード』により定義されるもの |
『文』とは一般的にはセミコロンまでの1行を示します。しかし以下のように1行に複数の文を記述したり、数行に渡って一つの文を記述できます。
================= x=0;y=0; y_pos = unit_height[max_enemy_handle] - unit_height[player_handle[net_id]]; =================このような記述の場合でもあくまでセミコロンまでを『文』と見なします。「文と見なします」とはif構文やfor構文などで条件や繰り返しの対象となる範囲を意味します。 例を挙げると以下のような記述の場合
================= if (reset_flag==TRUE) x=0;y=0; =================条件を満たす場合にxとyがゼロに初期化されるように見えますが、yはif構文の外側になるため、reset_flagの値に関わらず必ずゼロが代入されます。
このように、各種構文では一つの『文』のみを対象とします。そこで波括弧{ }を使うことで、「複数の『文』」を構文解析上「一つの『文』」にすることができます。
================= if (reset_flag==TRUE) {x=0;y=0;} =================if文、for文などで一般に波括弧{ }を使うのは文法上の要請ではなく、ifやforが一つの『文』を対象とすることが理由です。
『if構文』における『(条件判断)式』はint型、float型およびstring型の『式』であれば何でも構いません。条件式を実行した結果が「int型の場合は0以外」「float型の場合は0.0以外」「string型の場合は""以外」をTRUEとみなして、『文』を実行します。 FLASEの場合『else構文』もしくは『elseif構文』を実行します。
この『(条件判断)式』には関数も含まれます。関数を含む式を記述した場合、条件式の評価時に関数が実行されます。
なお『else構文』のうちelseifの定義を見ると最後に『else構文』が再帰的に含まれます。これは他の例だと関数の中の引数に関数があるのと同じように、else構文も再帰的に処理されます。「if ... elseif ... elseif ... else」という記述を見ると、あたかも同じ階層で条件判断が並んでいるように見えますが、 構文解析上は「if ... (elseif ... (elseif ... (elseif ... (else ...))))」という入れ子構造になっています。
『while構文』の『(条件判断)式』もif構文と同様です。int型、float型およびstring型の『式』がTRUEの場合のみ、『文』を実行します。『文』を実行した後は再度『(条件判断)式』を実行し、TRUEの場合には再度『文』を実行します。
「continue;」により定義される『continue文』を記述した場合、再度『(条件判断)式』を実行し、TRUEの場合に『文』を実行します。『(条件判断)式』の直前へのジャンプするように振舞います。
「break;」により定義される『break文』を記述した場合、『(条件判断)式』は一切評価も実行もされずに、『文』の次の文を実行します。見かけ上は「ループの外側にジャンプする」ように動作しますが、構文解析上は左記のような振る舞いとして定義されています。
『for構文』の基本的な仕組みは『while構文』と同様です。後述のcontinue文の例外を除き、概ね以下のように置き換えられます。
================= 『(初期化)式』; while(『(条件判断)式』) {『文』 『(繰り返し)式』;} =================『文』の中に記述したbreak文はwhile文同様に『文』(ここでは繰り返し式をまとめた文ブロックを意味する)の次の文にジャンプします。continue文に関しては『(繰り返し)式』の直前にジャンプします。『(条件判断)式』の直前にジャンプするwhile文とは異なります。