A CORBA IDL nyelv

Típusok, típuskonstrukciók

Interfész deklaráció

Az OMG IDL alapvető eleme az interfész deklaráció.

Példa:

interface A { attribute string Name; void make_it_so(); };

Szintaxis:

(4) <interface> ::= <interface_dcl> | <forward_dcl> (5) <interface_dcl> ::= <interface_header> “{” <interface_body> “}” (7) <interface_header> ::= [ “abstract” | “local” ] “interface” <identifier> [ <interface_inheritance_spec> ] (8) <interface_body> ::= <export>* (9) <export> ::= <type_dcl> “;” | <const_dcl> “;” | <except_dcl> “;” | <attr_dcl> “;” | <op_dcl> “;” | <type_id_dcl> “;” | <type_prefix_dcl> “;”

A következő alfejezetekben az interfészdeklaráció különböző részeit mutatjuk be.

Interfész fejléc

Egy interfész deklaráció fejléce a következő három elemet tartalmazhatja:

  1. Opcionális módosító: abstract és local kulcsszavakat.
  2. Az interfész neve (az interface kulcsszó után).
  3. Opcionális öröklődés specifikáció.

Az interfész neve egy azonosító, ami tetszőleges olyan helyen elofordulhat ahol egy azonosító szerepelhet. Egy attribútum típusaként az interfészt egy illeszkedő objektumra való referenciaként kell értelmezni. (Ennek részleteit a nyelvi leképezések adják meg.)

Interfész öröklődés specifikációja

Interfész öröklődés megadására az interfész neve és egy ":" után ","-vel elválasztva fel kell sorolni olyan elozőleg deklarált interfészek neveit, amelyeknek a specifikációját az interfésznek örökölnie kell.

Az interfész öröklődés a következő szintaxist követi:

(10)<interface_inheritance_spec>::=“:” <interface_name> { “,” <interface_name> }* (11) <interface_name> ::= <scoped_name> (12) <scoped_name> ::= <identifier> | “::” <identifier> | <scoped_name> “::” <identifier>

Interfész törzs

Egy interfész törzs a következőket tartalmazhatja:

Egy interfész deklaráció lehet üres is.

Interfész elődeklaráció

Elődeklaráció segítségével deklarálni lehet egy interfész nevét, anélkül, hogy a definicóját megadnánk. Erre egymásra hivatkozó interfészek esetén van szükség. Egy interfész elődeklarációja tetszőleges számban előfordulhat.

(6) <forward_dcl> ::= [ “abstract” | “local” ] “interface” <identifier>

Egy elődeklarált (azaz definíció nélküli) interfészból nem lehet származtatni (azaz örököltetni) egy másik interfészt.

Az interfész származtatás szabályai

Egy interfész származtatható egy másik interfészből. Ezt ős (vagy alap) interfésznek nevezünk. A származtatott interfész örökli az ős minden elemét és új elemeket (konstansokat, típusokat, attribútumokat, kivételeket és műveleteket) deklarálhat. Egy interfész tetszőleges számú ősbol származtatható (lásd többszörös öröklődés). Azokat az interfészeket amik az interfész deklaráció fejlécében az öröklődés-specifikációs részben szerepelnek, közvetlen ősnek nevezzük. Absztrakt interfészek csak absztrakt interfészekből származtathatók.

Hivatkozás az interfész elemekre egyértelmű kell legyen. Egy ős interfész egy elemére való hivatkozás nem egyértelmű ha a név több ős interfész definíciójában is szerepel konstansként, típusként vagy kivételként. Ebben az esetben az interfész nevével (a "::" hatókör operátort használva) minősített neveket kell képezni. Nem engedélyezett a származtatás két olyan interfészből amelyek azonos nevű műveletet vagy attribútumot tartalmaznak, és nem engedélyezett az örökölt műveletek és attribútumok felüldefiniálása sem.

Értéktípus deklaráció

Az értéktípusok olyan adatelemeket jelölnek, amik érték szerint adhatóak át CORBA távoli eljáráshívásokban. Ezek viszonylag újak az OMG IDL specifikációban. Régebbi verziók még nem tartalmazzák. Használatuk (különösen az öröklődéseket tekintve) néha eltér a hagyományos programnyelvekben (pl. C++-ban) megszokottaktól.

Többféle értéktípus deklaráció létezik: "reguláris" értéktípusok, dobozolt értéktípusok, és absztrakt értéktípusok, valamint értéktípus elődeklaráció.

(13) <value> ::= ( <value_dcl> | <value_abs_dcl> | <value_box_dcl> | <value_forward_dcl>)

Az alábbiakban a különböző értéktípus deklarációkat mutatjuk be részletesen.

Reguláris értéktípus

Egy reguláris értéktípus deklaráció egy fejlécből és "{..}" közé zárt értéktípus elemekből áll. Az értéktípusok származtathatók más, már meglevő értéktípusokból. A fejlécben az értéktípus neve és opcionálisan a származtatás módja (azaz az ősök) adhatóak meg.

Szintaxis:

(17) <value_dcl> ::= <value_header> “{“ < value_element>* “}” (18) <value_header> ::= [“custom” ] “valuetype” <identifier> [ <value_inheritance_spec> ] (19)<value_inheritance_spec> ::= [ “:” [ “truncatable” ] <value_name> { “,” <value_name> }* ] [ “supports” <interface_name> { “,” <interface_name> }* ] (20) <value_name> ::= <scoped_name>

Az értéktípus elemek állapot-tagokból és inicializátorokból állnak. Az állapot-tagok lehetnek publikusak (public) vagy rejtettek (private). Az inicializátorok lényegileg factory kulcsszóval bevezetett metódusok (lásd konstruktorok). Ezek a "metódusok" nem öröklődnek. Arra szolgálnak hogy egy értéktípust futási időben létrehozzunk. Nincsenek alapértelmezett inicializátorok.

(21) <value_element> ::= <export> | < state_member> | <init_dcl> (22) <state_member> ::= ( “public” | “private” ) <type_spec> <declarators> “;” (23) <init_dcl> ::= “factory” <identifier> “(“ [ <init_param_decls> ] “)” [ <raises_expr> ] “;” (24) <init_param_decls> ::= <init_param_decl> { “,” <init_param_decl> }* (25) <init_param_decl> ::= <init_param_attribute> <param_type_spec> <simple_declarator> (26) <init_param_attribute> ::= “in”

Példa:

interface Tree { void print() }; valuetype WeightedBinaryTree { // state definition private unsigned long weight; private WeightedBinaryTree left; private WeightedBinaryTree right; // initializer factory init(in unsigned long w); // local operations WeightSeq pre_order(); WeightSeq post_order(); }; valuetype WTree: WeightedBinaryTree supports Tree {};

Dobozolt értéktípus

A dobozolt értéktípus, olyan speciális értéktípusnak felel meg amit semmiből nem származtatnak, aminek nincsenek műveletei, és csak egyetlen állapot tagot tartalmaz.

(15) <value_box_dcl> ::= “valuetype” <identifier> <type_spec>

Az alábbi két példa fogalmilag ekvivalens:

module Example { interface Foo { /* anything */ }; valuetype FooSeq sequence; interface Bar { void doIt (in FooSeq seq); }; };
module Example { interface Foo { /* anything */ }; valuetype FooSeq { public sequence data; }; interface Bar { void doIt (in FooSeq seq); }; };

Absztrakt értéktípus

Az absztrakt értéktípusokat nem lehet példányosítani. Nincsenek állapot tagjai és inicializátorai. De lokális műveletek specifikálhatók. Az absztrakt értéktípusok tulajdonképpen csak lokális műveletek összefogására szolgál.

(16) <value_abs_dcl> ::= “abstract” “valuetype” <identifier> [ <value_inheritance_spec> ] “{“ <export>* “}”

Értéktípus elődeklaráció

(14) <value_forward_dcl> ::= [ “abstract” ] “valuetype” <identifier>

Értéktípusok származtatása

Az értéktípusok származtatására az interfészek származtatásához hasonló szabályok érvényesek. Egy értéktípus származtatható más értéktípusokból és egy értéktípus támogathat egy interfészt.

Konstans deklaráció

A konstans deklarációk arra szolgálnak, hogy konstans értékeknek nevet adjunk. A konstansoknak jól definiált típusuk van. Egész és lebegőpontos számliterálok között műveleteket is megadhatunk. Fordítási hiba generálódik, ha egy konstansnak olyan értéket adunk ami a típusával nem kompatibilis (pl. nem ábrázolható az adott típuson).

Példák:

const octet O1 = 0x1; const long L = 3; const octet O2 = 5 + L; enum Color { red, green, blue }; const Color FAVORITE_COLOR = red; module M { enum Size { small, medium, large }; }; const M::Size MYSIZE = M::medium;

A konstans deklaráció pontos szintaxisa:

(27) <const_dcl> ::= “const” <const_type> <identifier> “=” <const_exp> (28) <const_type> ::= <integer_type> | <char_type> | <wide_char_type> | <boolean_type> | <floating_pt_type> | <string_type> | <wide_string_type> | <fixed_pt_const_type> | <scoped_name> | <octet_type> (29) <const_exp> ::= <or_expr> (30) <or_expr> ::= <xor_expr> | <or_expr> “|” <xor_expr> (31) <xor_expr> ::= <and_expr> | <xor_expr> “^” <and_expr> (32) <and_expr> ::= <shift_expr> | <and_expr> “&” <shift_expr> (33) <shift_expr> ::= <add_expr> | <shift_expr> “>>” <add_expr> | <shift_expr> “<<” <add_expr> (34) <add_expr> ::= <mult_expr> | <add_expr> “+” <mult_expr> | <add_expr> “-” <mult_expr> (35) <mult_expr> ::= <unary_expr> | <mult_expr> “*” <unary_expr> | <mult_expr> “/” <unary_expr> | <mult_expr> “%” <unary_expr> (36) <unary_expr> ::= <unary_operator> <primary_expr> | <primary_expr> (37) <unary_operator> ::= “-” | “+” | “~” (38) <primary_expr> ::= <scoped_name> | <literal> | “(” <const_exp> “)” (39) <literal> ::= <integer_literal> | <string_literal> | <wide_string_literal> | <character_literal> | <wide_character_literal> | <fixed_pt_literal> | <floating_pt_literal> | <boolean_literal> (40) <boolean_literal> ::= “TRUE” | “FALSE” (41) <positive_int_const> ::= <const_exp>

Típus deklaráció

Arra szolgál hogy adattípusokat elnevezzünk illetve összetett típusokat hozzunk létre. A C nyelvhez hasonlóan a typedef kulcsszóval rendel azonosítókat a típusokhoz. Típuskonstrukcióra a struct, union, enum és a native kulcsszavak szolgálnak.

Szintaxis:

(42) <type_dcl> ::= “typedef” <type_declarator> | <struct_type> | <union_type> | <enum_type> | “native” <simple_declarator> | <constr_forward_decl> (43) <type_declarator> ::= <type_spec> <declarators> (44) <type_spec> ::= <simple_type_spec> | <constr_type_spec> (45) <simple_type_spec> ::= <base_type_spec> | <template_type_spec> | <scoped_name> (46) <base_type_spec> ::= <floating_pt_type> | <integer_type> | <char_type> | <wide_char_type> | <boolean_type> | <octet_type> | <any_type> | <object_type> | <value_base_type> (47) <template_type_spec> ::= <sequence_type> | <string_type> | <wide_string_type> | <fixed_pt_type> (48) <constr_type_spec> ::= <struct_type> | <union_type> | <enum_type> (49) <declarators> ::= <declarator> { “,” <declarator> }* (50) <declarator> ::= <simple_declarator> | <complex_declarator> (51) <simple_declarator> ::= <identifier> (52) <complex_declarator> ::= <array_declarator>

Alaptípusok

Egész és lebegőpontos szám, karakter, széles karakter, logikai, oktet és definiálatlan (any) típusok vannak.

Az egész típusok (a C nyelvben megismertekhez hasonlóan) short, unsigned short, long, unsigned long, long log és unsigned long long lehetnek. A lebegőpontos típusok (a C-hez hasonlóan) float, double és long double lehetnek.

A karakter típus (char) 8 bites mennyiségeket jelölhet. Értékei az ISO 8859-1 (Latin1) karakterkészletből kerülhetnek ki. A széles karakterek (wchar) mérete implementációfüggő.

A logikai típus értékei TRUE és FALSE lehetnek.

Az octet egy 8 bites mennyiséget jelölhet. Kommunikációs rendszereken való áthaladás Semmilyen átalakításon nem megy át

Az any segítségével tetszőleges (vagy definiálatlan) típusú értékeket specifikálhatunk. Az any tartalmaz egy TypeCode-ot ami a lehetőséget biztosít arra, hogy futási időben az érték tényleges típusát megkapjuk. A nyelvi leképezések lehetőséget biztosítanak rá, hogy a TypeCode-ot kiolvassuk.

Szintaxis:

(53) <floating_pt_type> ::= “float” | “double” | “long” “double” (54) <integer_type> ::= <signed_int> | <unsigned_int> (55) <signed_int> ::= <signed_short_int> | <signed_long_int> | <signed_longlong_int> (56) <signed_short_int> ::= “short” (57) <signed_long_int> ::= “long” (58) <signed_longlong_int> ::= “long” “long” (59) <unsigned_int> ::= <unsigned_short_int> | <unsigned_long_int> | <unsigned_longlong_int> (60) <unsigned_short_int> ::= “unsigned” “short” (61) <unsigned_long_int> ::= “unsigned” “long” (62) <unsigned_longlong_int> ::= “unsigned” “long” “long” (63) <char_type> ::= “char” (64) <wide_char_type> ::= “wchar” (65) <boolean_type> ::= “boolean” (66) <octet_type> ::= “octet” (67) <any_type> ::= “any” (68) <object_type> ::= “Object”

Összetett típusok

IDL-ben struktúrákat (struct), uniókat (union) és felsorolásokat (enum) a következő szintaxissal lehet létrehozni:

(42) <type_dcl> ::= “typedef” <type_declarator> | <struct_type> | <union_type> | <enum_type> | “native” <simple_declarator> | <constr_forward_decl> (48) <constr_type_spec> ::= <struct_type> | <union_type> | <enum_type> (99) <constr_forward_decl> ::= “struct” <identifier> | “union” <identifier>

Egy struktúra (struct) definiálása a következő képpen történhet:

(69) <struct_type> ::= “struct” <identifier> “{” <member_list> “}” (70) <member_list> ::= <member>+ (71) <member> ::= <type_spec> <declarators> “;”

A struktúra neve egy új legális típusnév. lehetőség van rá, hogy struktúráknak a typedef kulcsszóval adjunk nevet. Egy struktúra értékét az adattagjainak az értéke adja meg.

Unió definiálásánál egy ún. diszkriminánst is meg kell adni:

(72) <union_type> ::= “union” <identifier> “switch” “(” <switch_type_spec> “)” “{” <switch_body> “}” (73) <switch_type_spec> ::= <integer_type> | <char_type> | <boolean_type> | <enum_type> | <scoped_name> (74) <switch_body> ::= <case>+ (75) <case> ::= <case_label>+ <element_spec> “;” (76) <case_label> ::= “case” <const_exp> “:” | “default” “:” (77) <element_spec> ::= <type_spec> <declarator>

Az OMG ILD uniója (union) kombinálja a C union és switch szerkezeteit. A union definíció fejléce egy típust specifikál aminek az értékei meghatározzák hogy egy adott esetben az unió melyik tagját kell használni. Egy alapértelmezett tag is használható. A diszkrimináns típus valamilyen előzőleg definiált integer, char, boolean vagy enum lehet. Az union egy új legális típust definiál. lehetőség van rá, hogy uniókat typedef segítségével nevezzünk el.

A felsorolások (enum) azonosítók egy rendezett listájából állnak. Egy felsorolás a következő szintaxissal adható meg:

(78) <enum_type> ::= “enum” <identifier> “{” <enumerator> { “,” <enumerator> }* “}” (79) <enumerator> ::= <identifier>

Az enum egy új legális típust definiál.

Sablonos típusok

Az OMG IDL ún. sablonos típusok segítségével lehetőséget biztosít szekvenciák, hagyományos és széles stringek, valamit fix-pontos valós számok használatára.

(47) <template_type_spec> ::= <sequence_type> | <string_type> | <wide_string_type> | <fixed_pt_type>

Az OMG IDL szekvenciája (sequence) egy egy-dimenziós tömb aminek van egy maximális mérete (ez fordítási időben rögzített) és egy hossza (ami futási időben változhat).

(80) <sequence_type> ::= “sequence” “<” <simple_type_spec> “,” <positive_int_const> “>” | “sequence” “<” <simple_type_spec> “>”

A fenti szintaxis szerint a sequence "sablon" első paramétere a szekvencia elemeinek a típusa, míg a második (opcionális) paraméter a szekvencia maximális hossza.

Egy szekvencia elemeinek típusa lehet szekvencia is. Pl:

typedef sequence< sequence > Fred;

Stringek a következő szintaxissal deklarálhatók:

(81) <string_type> ::= “string” “<” <positive_int_const> “>” | “string” (82) <wide_string_type> ::= “wstring” “<” <positive_int_const> “>” | “wstring”

A stringek tulajdonképpen (hagyományos vagy széles) karakterek szekvenciájának felelnek meg. A string és wstring sablonok opcionális paramétere a karakter-szekvencia maximális hosszát adják meg. lehetőség van arra is, hogy a stringek tetszőleges hosszúak legyenek. A nyelvi leképezéseknek ezt kezelni kell. Előfordulhat azonban, hogy ez csak kevésbé hatékony módon valósítható meg, mint a rögzített maximális hosszal rendelkező stringek. Egy string hossza (mindkét esetben) futási időben változhat.

A fixed "sablonnal" fix-pontos decimális számokat reprezentálhatunk maximum 31 szignifikáns számértékig.

(96) <fixed_pt_type> ::= “fixed” “<“ <positive_int_const> “,” <positive_int_const> “>” (97) <fixed_pt_const_type> ::= “fixed”

Tömbök

OMG IDL-ben több-dimenziós, rögzített méretű tömbök definiálhatók a következő szintaxissal:

(83) <array_declarator> ::= <identifier> <fixed_array_size>+ (84) <fixed_array_size> ::= “[” <positive_int_const> “]”

A tömb-indexek implementációja függhet a nyelvi leképezéstől, ezért paraméterként való átadása hibát okozhat.

Művelet és attribútum deklarációk

Művelet deklaráció

Lásd. az alprogramok c. fejezetnél.

Attribútum deklaráció

Egy interfészben nem csak műveletek, hanem attribútumok is lehetnek. Egy attribútumnak alapértelmezésben két hozzáférési (egy írási és egy olvasási) művelet felel meg, viszont a readonly attribútumokhoz nem tartozik írási művelet.

Példa:

interface foo { enum material_t {rubber, glass}; struct position_t { float x, y; }; attribute float radius; attribute material_t material; readonly attribute position_t position; • • • };

Szintaxis:

(85) <attr_dcl> ::= <readonly_attr_spec> | <attr_spec> (104) <readonly_attr_spec> ::= “readonly” “attribute” <param_type_spec> <readonly_attr_declarator> (105)<readonly_attr_declarator >::= <simple_declarator> <raises_expr> | <simple_declarator> { “,” <simple_declarator> }* (106) <attr_spec> ::= “attribute” <param_type_spec> <attr_declarator> (107) <attr_declarator> ::= <simple_declarator> <attr_raises_expr> | <simple_declarator> { “,” <simple_declarator> }*