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:
- Opcionális módosító: abstract és local kulcsszavakat.
- Az interfész neve (az interface kulcsszó után).
- 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:
- Konstans deklaráció.
- Típus deklaráció.
- Kivétel deklaráció.
- Attribútum deklaráció.
- Művelet deklaráció.
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> }*