Last Modified: 2020/02/10 23:46:18.
Only available in Japanese text.
Kuin関連情報の個人的まとめに戻る
Extensible Markup Language (XML) 1.0 (Fifth Edition)に準ずる表記法です。
BNFを拡張した表記法ですが、EBNF や ABNFではありません。
上記リンク先の記法と異なる点が4つあります。
KuinSource ::= ( +? Definition )* 』 // 定義文の集まり // Kuinのソースファイルの拡張子は.knです。 // Kuinのソースファイルは UTF-8 で書いてください。 // + ⇒ 他のファイルで参照可能な宣言。
Sentence ::= Definition | // 定義文 BlockSentence | // ブロック文 SimpleSentence 』 // 単文
Definition ::= Func | Var | Const | Alias | Class | Enum 』
Func ::= func ([ DllName ])? FName ( (VName : &? Type( , VName : &? Type )*)? )( : Type)? Sentence* end func 』 // & を付けなければ値渡し、& を付けると参照渡しになります。 // 参照渡しの際は、 関数定義の仮引数 と 関数呼び出しの実引数 の両方に & を付けます。 // 例:func f(x : &int) に対し、do f(&i)
Var ::= var VName : Type( :: Expr)? 』 // 代入( :: Expr)を省略した場合、すべて0で初期化されます。 // グローバル変数・メンバ変数では、定義時には値を代入できません。 // 定義と同時に値を代入できるのは、ローカル変数のみです。
Const ::= const VName : Type :: ConstExpr 』
Alias ::= alias Type : Type 』// alias 新しい型名: 既存の型名
Class ::= class CName ( ClassName? ) ( +? *? Definition )* end class 』 // 継承元( ClassName )を省略した場合、Kuin@CClass が継承されます。 // 全てのクラスは、ルートクラスである Kuin@CClass が継承されていると言えます。 // 例: class CCat : CAnimalとした場合、Kuin@CClass → CAnimal → CCat // 多重継承はできません。 // // + ⇒ パブリックなメンバ。(※varとfuncのみに可能。) // * ⇒ 親クラスのメンバのオーバーライドを許可。(funcのみに可能) // * は、+ の後に記述しなければエラーとなります。 // (誰が書いても同じようなコードにするため) // オーバーライドできるのはメソッドのみです。 // // コンストラクタは、*func ctor() // デストラクタは、*func dtor() // // { インスタンスを作って初期化(Init)する方法 } [出典: @yuhi_as] // { クラスのinitメソッドの宣言 } // class MyClass() // var メンバ変数: ~ // +func init(仮引数): MyClass // do me.メンバ変数 :: ~ // ret me // end func // end class // { 呼び方 } // var c : MyClass :: (#MyClass).init(実引数)
Enum ::= enum EName ( ConstName( :: ConstExpr)? )* end enum 』 // :: Exprを指定しなかったときのデフォルト値は 0 から始まります。 // 値は自動的に 1 ずつ足されて設定されます。 // 下記の例では、red は 0、green は 1、yellow は 6に設定されます。 // enum Color // red // green // blue :: 5 // yellow // end enum // 他の要素と値が重複した場合は、コンパイルエラーとなります。
BlockStatement ::= If | Switch | While | For | Try | Block 』 // ブロック内で定義したローカル変数は、そのブロック内でのみ参照できます。
If ::= if BlockName? ( Expr ) Sentence* ( elif ( Expr ) Sentence* )* ( else Sentence* )? end if 』 // 条件式 (()の中身)は、bool型でなければなりません。
Switch ::= switch BlockName? ( Expr ) ( case Value Sentence* )* ( default Sentence* )? end switch 』 // case の最後に達した段階で自動でブロックを抜けます (フォールスルーできません)。 // Value は、カンマ区切りで複数指定できます。また、to により、範囲指定もできます。 // 上記のExprの型とValueの定義中のExprの型は一致しなければなりません。 // Exprに指定できる型: int、ビット型(bit16など)、char、enum、[]char // Value は、コンパイル時に定数とならなくても構いません。 // 複数の case条件に合致する場合、その中の最初のcaseに捕捉されます。
While ::= while BlockName? ( ( Expr( , skip )? )? ) Sentence* end while 』 // 条件式を省略すると無限ループになります。 // 条件式は bool型でなくてはなりません。 // skipを指定した場合、初回の条件比較をスキップします (C言語のdo-whileの代替)。
For ::= for BlockName? ( Expr , Expr( , ConstExpr)? ) Sentence* end for 』 // BlockNameがループカウンタ変数の役割をします。(int型) // 括弧内(()内)は順に、初期値、終値、増減値です(全てint型)。 // // 増減値が正の数ならば i <= 終値 がループ続行の条件となります。 // 増減値が負の数ならば i >= 終値 がループ続行の条件となります。 // 増減値が0の場合はコンパイルエラーになります。 // 増減値を省略した場合、増減値は1になります。
Try ::= try BlockName? Sentence* ( catch Value? Sentence* )+ ( finally Sentence* )? end try 』 // 上記のValueで例外コード(int型)を指定します(複数指定可能)。 // Valueを省略すると、1000以上のすべての例外コードが捕捉されます。 // catchで指定する例外コードは、コンパイル時に定数とならなくてはなりません。 // 例外の情報は、ブロック名(ここではeとします)を用いて、e.Code、e.Msg のように参照できます。 // eはKuin@CExcptクラスに属しており、例外が発生したソースコード上の箇所がこの変数に格納されています。 // e.Code は例外コード(int型)、e.Msg はメッセージ([]char型)です。 // tryやcatch中でbreakした場合、finallyを通ります。 // finally内で そのtry文をbreakすると、無限ループになってしまうので注意してください。
Block ::= block BlockName? Sentence* end block 』 // 単純に、ブロック構造を作りたいときに有効です。
SimpleSentence ::= Do | Break | Skip | Return | Assert | Throw 』
Do ::= do Variable OpSubstitution Expr | // 代入 do Variable OpSwap Variable | // 値の交換 do FunctionCall 』 // 関数呼び出し // 代入文では、両辺が参照型の場合、値ではなくアドレスが代入されます。 // do文は副作用のある演算子で終わる必要があります。 [出典: Kuinのコンパイルエラー一覧(非公式) #E0054] // do true ?(f(&a), f(&b))はコンパイルエラーになります。(do の直後が代入でも関数呼び出しでもなく条件演算) // 上記のような場合はifを使うべきです。
Break ::= break BlockName 』 // BlockNameで指定したブロックを抜けます。 // 全てのブロック文でbreak可能です。
Skip ::= skip BlockName 』 // BlockNameで指定したブロックの終端(end)直前にジャンプします。 // skip可能なブロックは、while、forです。
Return ::= ret Expr? 』 // 戻り値が無い関数では、値を省略して ret のみを記述します。
Assert ::= assert Expr 』 // 上記のExprはbool型でなければなりません。 // 例: assert a >= 2 // このとき、デバッグ実行時に a が 2以上でなければ、例外が投げられます。 // a が 2以上であることが保証されるべき場面での、テストに用いられます。 // リリース時にはコンパイルから外されますので、最終的な動作速度に影響しません。
Throw ::= throw Expr( , Expr)? 』 // 1つ目のExprは例外コード( int型 ) // 2つ目のExprは例外メッセージ( []char型 ) // 例外メッセージを省略した場合、例外メッセージに null が入ります。
Expr ::= ( Expr ) | String | Char | Boolean | Number | // リテラル Variable | ConstantName | // 変数・定数 BlockName | // (Forなどの)ブロック名 Op1 Expr | // 単項演算 Expr Op2 Expr | // 二項演算 OpType1 Type | // インスタンスの作成(#) Expr OpType2 Type | // キャスト演算($) Expr OpClass2 ClassName | // クラスチェック(=:、<>:) Expr ?( Expr , Expr ) | // 条件演算 FunctionCall 』 // 関数呼び出し // 条件演算の ? と ( の間にスペースを入れてはいけません。 // true ?(A, B)の場合はAのみ、false ?(A, B)の場合はBのみが評価されます。 ConstExpr ::= Expr 』 // コンパイル時に定数となる式を、ここではConstExprと表記しています。 Variable ::= VariableName | Variable [ Expr ] 』 // 配列アクセス // デバッグ実行時に配列の範囲外をアクセスすると、例外が投げられます。 // 例えば、s[5]まで定義されている配列があるとして、 s[-1] や s[6] は例外発生です。 // これにより、バグによるメモリ破壊を未然に防止できます。
String ::= " ( [^"] | \" )* " | null 』
Char ::= ' ( [^'\] | EscapedCh ) ' 』 EscapedCh ::= \\ | // 「\」 \" | // 「"」 \' | // 「'」 \0 | // 文字コード0の文字 \n | // 改行文字 \t | // タブ文字 \u???? | // 指定した文字コードの文字。 「????」には数字または大文字アルファベットで4桁の16進数を指定 \{式} | // 式の結果を文字列化したもの。 例えば、int型変数nに3が格納されているとき、 //「"\{n+5}"」と記述すると「"8"」と解釈される。 「(式).toStr()」と等しい
Boolean ::= true | false 』
Number ::= [+-]?NonNegativeNumber | inf』 // inf は float型 のリテラルです。 NonNegativeNumber ::= Base10 | Base16 』 // 10進数, 16進数 Base10 ::= [0-9]+(.[0-9]+(e[+-][0-9]+)?)? 』 Base16 ::= 0x[0-9A-F]+ 』
Name ::= [A-Za-z_][0-9A-Za-z_]* 』 SourceName ::= Name 』 // ソースコード名 BlockName ::= Name 』 // ブロック名 ClassName ::= Name 』 // 定義時のクラス名 ConstName ::= Name 』 // 定義時の定数名 AName ::= Name 』 // 定義時の別名 FName ::= Name 』 // 定義時の関数名 VName ::= Name 』 // 定義時の変数名 EName ::= Name 』 // 定義時の列挙体名 FunctionName ::= (SourceName?@)?(ClassName.)*FName 』 // アクセス時の関数名 VariableName ::= (SourceName?@)?(ClassName.)*VName 』 // アクセス時の変数名 EnumName ::= (SourceName?@)?((ClassName.)*ClassName#)?EName 』 // アクセス時の列挙体名 ConstantName ::= (SourceName?@)?((ClassName.)*ClassName#)?ConstName | EnumName#ConstName 』 // 別のファイルで定義された識別子のアクセス時には「SourceName@」が必要です。 // 同じファイルで定義されたグローバル変数のアクセス時には「@」のみが必要です。 // enumの要素にアクセスする記法の例: Test@C#E#Hoge // (ソースTest 内のクラスC 内の列挙体E 内の要素Hogeにアクセス) // ドットではなく#を使用する理由は、Kuinでは、静的なものは静的に処理したいので、 // 字句解析の段階で名前を決定しているためです。
// 代入演算子が = ではなく、::なのが特徴的です。 // C言語の ==, !=, &&, || は、Kuinではそれぞれ、=, <>, &, | に対応します。 // &, | はC言語の&&, ||と同様に短絡評価される論理演算子です。 // インクリメント演算子はありません。i :+ 1 で代用してください。 Op1 ::= + | - | ! | ^ 』 // 単項演算子 (符号, 論理否定, 要素数演算子) Op2 ::= + | - | * | / | // 二項演算子 (加減乗除) % | ^ | // 剰余、累乗 < | > | <= | >= | // 比較 = | <> | // 等価、不等価 =& | <>& | // 参照の等価、参照の不等価 (nullと比較するときはこれ) & | | | // 論理積、論理和 ~ 』 // 配列連結 OpType1 ::= # | // インスタンスの作成 #[ ... ] | // 配列のインスタンス生成。 例: #[5]int [ ... ] | // 動的配列のインスタンス生成。 例: var a: []int :: [1, 2, 3]int {※Kuin 1.01では[1, 2, 3]intではなく[1, 2, 3]と書く。} ## 』 // 参照型変数のディープコピー OpType2 ::= $ 』 // キャスト演算子 OpClass2 ::= =$ | <>$ 』 // 型比較演算子 Kuin 1.00のReadme.pdfで「要素比較演算子」(is, nisに相当)と書かれてる =#と同じものだとすると、 例えば、 a =$ c で変数aのクラスがcの場合に真となります。} OpSubstitution ::= :: | // 代入演算子 :+ | :- | :* | :/ | :% | :^ | :~ 』 // 複合代入演算子 OpSwap ::= :$ 』 // swap演算子 (a :$ bで、変数a と 変数b の値が入れ替わります。) // 代入演算やswap演算の戻り値はvoidです。 OpFunctionCall ::= ( ... ) 』 // 関数呼び出し OpArrayAccess ::= [ ... ] 』 // 配列の要素アクセス OpMemberAccess ::= . 』 // メンバアクセス OpCondition ::= ?( ... , ... ) 』 // 条件演算
FunctionCall ::= Function ( (&? Expr( , &? Expr)*)? ) | Expr . FunctionCall 』 // (2).toStr()などのメソッド呼び出し // 数値型のメソッドを利用する際、例えば5.toStr() ではなく、 // (5).toStr() または 5 .toStr() とする必要があります。 Function ::= FunctionName | Variable | ConstantName 』 // 関数型で定義された変数・定数
Type ::= int | float | char | bool | // 符号付整数型・浮動小数点型・文字型・論理型 bit8 | bit16 | bit32 | bit64 | // ビット型 list < Type > | // リスト構造 stack < Type > | // スタック構造 queue < Type > | // キュー構造 dict < Type , Type > | // 辞書型 (Kuin 1.01以降で使えます) func < ( (&? Type( , &? Type)*)? ) (: Type)? > | // 関数型 EnumName | ClassName | // 列挙体・クラス [ ] Type 』 // 動的配列 // complex/money/ratio型 はしばらく仕様から外れることになりました。[詳細: @b2] // Kuinでは型が厳密に扱われます。暗黙の型変換はできません。 // 配列は、var array:[]int :: @new [5]int のように宣言でき、 // array :~ @new [2]int のように要素数を増やせます。 // ※2016/03/20追記 : Kuin 1.01では @newの代わりに#を使うのが正しい?(ちゃんと確認していません。うろ覚え。)
Value ::= Expr( to Expr)?( , Value)* 』 // switch文・try文で用いる値の指定方法です。 // Exprの型はそれぞれの文で制限されています。
Comment ::= { ( [^"'{}]+ | String | Char | Comment )* } | ; .* 』 // Kuinでは、コメントがネストできます。 // また、コメント内部に文字列リテラル、文字リテラルを含み得ます。 // 例えば、{ " }" { } }は全体がコメント扱いされます。 // 行頭以降のタブ文字と半角空白以外に登場する文字が「;」である行は一行コメントになります。
誤表記等を発見された場合、@tatt61880にご連絡頂けると幸いです。
#Kuin Kuinの拡張バッカス・ナウア記法 (非公式) http://t.co/kw06gJLQ 完成しました! 非公式ですが、Kuinの文法のまとめとしてもご利用頂けると思います。
— たっと (@tatt61880) 2012年8月18日
Kuin関連情報の個人的まとめに戻る
This page has been described by Tatt (tatt61880) ---- Twitter: @tatt61880