%{ // ********************************************************************** // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #include #include #include #include #ifdef _MSC_VER // I get these warnings from some bison versions: // warning C4102: 'yyoverflowlab' : unreferenced label # pragma warning( disable : 4102 ) // warning C4065: switch statement contains 'default' but no 'case' labels # pragma warning( disable : 4065 ) #endif // // Avoid old style cast warnings in generated grammar // #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wold-style-cast" #endif using namespace std; using namespace Slice; void slice_error(const char* s) { // yacc and recent versions of Bison use "syntax error" instead // of "parse error". if (strcmp(s, "parse error") == 0) { unit->error("syntax error"); } else { unit->error(s); } } %} %pure_parser // // All keyword tokens. Make sure to modify the "keyword" rule in this // file if the list of keywords is changed. Also make sure to add the // keyword to the keyword table in Scanner.l. // %token ICE_MODULE %token ICE_CLASS %token ICE_INTERFACE %token ICE_EXCEPTION %token ICE_STRUCT %token ICE_SEQUENCE %token ICE_DICTIONARY %token ICE_ENUM %token ICE_OUT %token ICE_EXTENDS %token ICE_IMPLEMENTS %token ICE_THROWS %token ICE_VOID %token ICE_BYTE %token ICE_BOOL %token ICE_SHORT %token ICE_INT %token ICE_LONG %token ICE_FLOAT %token ICE_DOUBLE %token ICE_STRING %token ICE_OBJECT %token ICE_LOCAL_OBJECT %token ICE_LOCAL %token ICE_CONST %token ICE_FALSE %token ICE_TRUE %token ICE_IDEMPOTENT %token ICE_OPTIONAL // // Other tokens. // %token ICE_SCOPE_DELIMITER %token ICE_IDENTIFIER %token ICE_STRING_LITERAL %token ICE_INTEGER_LITERAL %token ICE_FLOATING_POINT_LITERAL %token ICE_IDENT_OP %token ICE_KEYWORD_OP %token ICE_OPTIONAL_OP %token ICE_METADATA_OPEN %token ICE_METADATA_CLOSE %token ICE_GLOBAL_METADATA_OPEN %token ICE_GLOBAL_METADATA_CLOSE %token BAD_CHAR %% // ---------------------------------------------------------------------- start // ---------------------------------------------------------------------- : definitions { } ; // ---------------------------------------------------------------------- global_meta_data // ---------------------------------------------------------------------- : ICE_GLOBAL_METADATA_OPEN string_list ICE_GLOBAL_METADATA_CLOSE { $$ = $2; } ; // ---------------------------------------------------------------------- meta_data // ---------------------------------------------------------------------- : ICE_METADATA_OPEN string_list ICE_METADATA_CLOSE { $$ = $2; } | { $$ = new StringListTok; } ; // ---------------------------------------------------------------------- definitions // ---------------------------------------------------------------------- : global_meta_data { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); if(!metaData->v.empty()) { unit->addGlobalMetaData(metaData->v); } } definitions | meta_data definition { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); ContainedPtr contained = ContainedPtr::dynamicCast($2); if(contained && !metaData->v.empty()) { contained->setMetaData(metaData->v); } } ';' definitions | error ';' { yyerrok; } definitions | meta_data definition { unit->error("`;' missing after definition"); } | { } ; // ---------------------------------------------------------------------- definition // ---------------------------------------------------------------------- : module_def { assert($1 == 0 || ModulePtr::dynamicCast($1)); } | class_decl { assert($1 == 0 || ClassDeclPtr::dynamicCast($1)); } | class_def { assert($1 == 0 || ClassDefPtr::dynamicCast($1)); } | interface_decl { assert($1 == 0 || ClassDeclPtr::dynamicCast($1)); } | interface_def { assert($1 == 0 || ClassDefPtr::dynamicCast($1)); } | exception_decl { assert($1 == 0); } | exception_def { assert($1 == 0 || ExceptionPtr::dynamicCast($1)); } | struct_decl { assert($1 == 0); } | struct_def { assert($1 == 0 || StructPtr::dynamicCast($1)); } | sequence_def { assert($1 == 0 || SequencePtr::dynamicCast($1)); } | dictionary_def { assert($1 == 0 || DictionaryPtr::dynamicCast($1)); } | enum_def { assert($1 == 0 || EnumPtr::dynamicCast($1)); } | const_def { assert($1 == 0 || ConstPtr::dynamicCast($1)); } ; // ---------------------------------------------------------------------- module_def // ---------------------------------------------------------------------- : ICE_MODULE ICE_IDENTIFIER { unit->setSeenDefinition(); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ModulePtr module = cont->createModule(ident->v); if(module) { cont->checkIntroduced(ident->v, module); unit->pushContainer(module); $$ = module; } else { $$ = 0; } } '{' definitions '}' { if($3) { unit->popContainer(); $$ = $3; } else { $$ = 0; } } ; // ---------------------------------------------------------------------- exception_id // ---------------------------------------------------------------------- : ICE_EXCEPTION ICE_IDENTIFIER { $$ = $2; } | ICE_EXCEPTION keyword { StringTokPtr ident = StringTokPtr::dynamicCast($2); unit->error("keyword `" + ident->v + "' cannot be used as exception name"); $$ = $2; // Dummy } ; // ---------------------------------------------------------------------- exception_decl // ---------------------------------------------------------------------- : local_qualifier exception_id { unit->error("exceptions cannot be forward declared"); $$ = 0; } ; // ---------------------------------------------------------------------- exception_def // ---------------------------------------------------------------------- : local_qualifier exception_id exception_extends { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ExceptionPtr base = ExceptionPtr::dynamicCast($3); ContainerPtr cont = unit->currentContainer(); ExceptionPtr ex = cont->createException(ident->v, base, local->v); if(ex) { cont->checkIntroduced(ident->v, ex); unit->pushContainer(ex); } $$ = ex; } '{' exception_exports '}' { if($4) { unit->popContainer(); } $$ = $4; } ; // ---------------------------------------------------------------------- exception_extends // ---------------------------------------------------------------------- : ICE_EXTENDS scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ContainedPtr contained = cont->lookupException(scoped->v); cont->checkIntroduced(scoped->v); $$ = contained; } | { $$ = 0; } ; // ---------------------------------------------------------------------- exception_exports // ---------------------------------------------------------------------- : meta_data exception_export ';' exception_exports { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); ContainedPtr contained = ContainedPtr::dynamicCast($2); if(contained && !metaData->v.empty()) { contained->setMetaData(metaData->v); } } | error ';' exception_exports { } | meta_data exception_export { unit->error("`;' missing after definition"); } | { } ; // ---------------------------------------------------------------------- type_id // ---------------------------------------------------------------------- : type ICE_IDENTIFIER { TypePtr type = TypePtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); TypeStringTokPtr typestring = new TypeStringTok; typestring->v = make_pair(type, ident->v); $$ = typestring; } ; // ---------------------------------------------------------------------- optional // ---------------------------------------------------------------------- : ICE_OPTIONAL_OP ICE_INTEGER_LITERAL ')' { IntegerTokPtr i = IntegerTokPtr::dynamicCast($2); int tag; if(i->v < 0 || i->v > Int32Max) { unit->error("tag for optional is out of range"); tag = -1; } else { tag = static_cast(i->v); } OptionalDefTokPtr m = new OptionalDefTok; m->v.optional = tag >= 0; m->v.tag = tag; $$ = m; } | ICE_OPTIONAL_OP scoped_name ')' { StringTokPtr scoped = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); assert(cont); ContainedList cl = cont->lookupContained(scoped->v); if(cl.empty()) { YYERROR; // Can't continue, jump to next yyerrok } cont->checkIntroduced(scoped->v); int tag = -1; EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front()); ConstPtr constant = ConstPtr::dynamicCast(cl.front()); if(constant) { BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type()); if(b) { switch(b->kind()) { case Builtin::KindByte: case Builtin::KindShort: case Builtin::KindInt: case Builtin::KindLong: { IceUtil::Int64 l = IceUtilInternal::strToInt64(constant->value().c_str(), 0, 0); if(l < 0 || l > Int32Max) { unit->error("tag for optional is out of range"); } tag = static_cast(l); break; } default: break; } } } else if(enumerator) { tag = enumerator->value(); } if(tag < 0) { unit->error("invalid tag `" + scoped->v + "' for optional"); } OptionalDefTokPtr m = new OptionalDefTok; m->v.optional = tag >= 0; m->v.tag = tag; $$ = m; } | ICE_OPTIONAL_OP ')' { unit->error("missing tag for optional"); OptionalDefTokPtr m = new OptionalDefTok; // Dummy m->v.optional = false; m->v.tag = -1; $$ = m; } | ICE_OPTIONAL { unit->error("missing tag for optional"); OptionalDefTokPtr m = new OptionalDefTok; // Dummy m->v.optional = false; m->v.tag = -1; $$ = m; } ; // ---------------------------------------------------------------------- optional_type_id // ---------------------------------------------------------------------- : optional type_id { OptionalDefTokPtr m = OptionalDefTokPtr::dynamicCast($1); TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2); m->v.type = ts->v.first; m->v.name = ts->v.second; $$ = m; } | type_id { TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1); OptionalDefTokPtr m = new OptionalDefTok; m->v.type = ts->v.first; m->v.name = ts->v.second; m->v.optional = false; m->v.tag = -1; $$ = m; } ; // ---------------------------------------------------------------------- exception_export // ---------------------------------------------------------------------- : data_member ; // ---------------------------------------------------------------------- struct_id // ---------------------------------------------------------------------- : ICE_STRUCT ICE_IDENTIFIER { $$ = $2; } | ICE_STRUCT keyword { StringTokPtr ident = StringTokPtr::dynamicCast($2); unit->error("keyword `" + ident->v + "' cannot be used as struct name"); $$ = $2; // Dummy } ; // ---------------------------------------------------------------------- struct_decl // ---------------------------------------------------------------------- : local_qualifier struct_id { unit->error("structs cannot be forward declared"); $$ = 0; // Dummy } ; // ---------------------------------------------------------------------- struct_def // ---------------------------------------------------------------------- : local_qualifier struct_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); StructPtr st = cont->createStruct(ident->v, local->v); if(st) { cont->checkIntroduced(ident->v, st); unit->pushContainer(st); } else { st = cont->createStruct(IceUtil::generateUUID(), local->v); // Dummy assert(st); unit->pushContainer(st); } $$ = st; } '{' struct_exports '}' { if($3) { unit->popContainer(); } $$ = $3; // // Empty structures are not allowed // StructPtr st = StructPtr::dynamicCast($$); assert(st); if(st->dataMembers().empty()) { unit->error("struct `" + st->name() + "' must have at least one member"); // $$ is a dummy } } ; // ---------------------------------------------------------------------- struct_exports // ---------------------------------------------------------------------- : meta_data struct_export ';' struct_exports { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); ContainedPtr contained = ContainedPtr::dynamicCast($2); if(contained && !metaData->v.empty()) { contained->setMetaData(metaData->v); } } | error ';' struct_exports { } | meta_data struct_export { unit->error("`;' missing after definition"); } | { } ; // ---------------------------------------------------------------------- struct_export // ---------------------------------------------------------------------- : struct_data_member ; // ---------------------------------------------------------------------- class_name // ---------------------------------------------------------------------- : ICE_CLASS ICE_IDENTIFIER { $$ = $2; } | ICE_CLASS keyword { StringTokPtr ident = StringTokPtr::dynamicCast($2); unit->error("keyword `" + ident->v + "' cannot be used as class name"); $$ = $2; // Dummy } ; // ---------------------------------------------------------------------- class_id // ---------------------------------------------------------------------- : ICE_CLASS ICE_IDENT_OP ICE_INTEGER_LITERAL ')' { IceUtil::Int64 id = IntegerTokPtr::dynamicCast($3)->v; if(id < 0) { unit->error("invalid compact id for class: id must be a positive integer"); } else if(id > Int32Max) { unit->error("invalid compact id for class: value is out of range"); } else { string typeId = unit->getTypeId(static_cast(id)); if(!typeId.empty() && !unit->ignRedefs()) { unit->error("invalid compact id for class: already assigned to class `" + typeId + "'"); } } ClassIdTokPtr classId = new ClassIdTok(); classId->v = StringTokPtr::dynamicCast($2)->v; classId->t = static_cast(id); $$ = classId; } | ICE_CLASS ICE_IDENT_OP scoped_name ')' { StringTokPtr scoped = StringTokPtr::dynamicCast($3); ContainerPtr cont = unit->currentContainer(); assert(cont); ContainedList cl = cont->lookupContained(scoped->v); if(cl.empty()) { YYERROR; // Can't continue, jump to next yyerrok } cont->checkIntroduced(scoped->v); int id = -1; EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front()); ConstPtr constant = ConstPtr::dynamicCast(cl.front()); if(constant) { BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type()); if(b) { switch(b->kind()) { case Builtin::KindByte: case Builtin::KindShort: case Builtin::KindInt: case Builtin::KindLong: { IceUtil::Int64 l = IceUtilInternal::strToInt64(constant->value().c_str(), 0, 0); if(l < 0 || l > Int32Max) { unit->error("compact id for class is out of range"); } id = static_cast(l); break; } default: break; } } } else if(enumerator) { id = enumerator->value(); } if(id < 0) { unit->error("invalid compact id for class: id must be a positive integer"); } else { string typeId = unit->getTypeId(id); if(!typeId.empty() && !unit->ignRedefs()) { unit->error("invalid compact id for class: already assigned to class `" + typeId + "'"); } } ClassIdTokPtr classId = new ClassIdTok(); classId->v = StringTokPtr::dynamicCast($2)->v; classId->t = id; $$ = classId; } | class_name { ClassIdTokPtr classId = new ClassIdTok(); classId->v = StringTokPtr::dynamicCast($1)->v; classId->t = -1; $$ = classId; } ; // ---------------------------------------------------------------------- class_decl // ---------------------------------------------------------------------- : local_qualifier class_name { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ClassDeclPtr cl = cont->createClassDecl(ident->v, false, local->v); $$ = cl; } ; // ---------------------------------------------------------------------- class_def // ---------------------------------------------------------------------- : local_qualifier class_id class_extends implements { BoolTokPtr local = BoolTokPtr::dynamicCast($1); ClassIdTokPtr ident = ClassIdTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ClassDefPtr base = ClassDefPtr::dynamicCast($3); ClassListTokPtr bases = ClassListTokPtr::dynamicCast($4); if(base) { bases->v.push_front(base); } ClassDefPtr cl = cont->createClassDef(ident->v, ident->t, false, bases->v, local->v); if(cl) { cont->checkIntroduced(ident->v, cl); unit->pushContainer(cl); $$ = cl; } else { $$ = 0; } } '{' class_exports '}' { if($5) { unit->popContainer(); $$ = $5; } else { $$ = 0; } } ; // ---------------------------------------------------------------------- class_extends // ---------------------------------------------------------------------- : ICE_EXTENDS scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); TypeList types = cont->lookupType(scoped->v); $$ = 0; if(!types.empty()) { ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front()); if(!cl || cl->isInterface()) { string msg = "`"; msg += scoped->v; msg += "' is not a class"; unit->error(msg); } else { ClassDefPtr def = cl->definition(); if(!def) { string msg = "`"; msg += scoped->v; msg += "' has been declared but not defined"; unit->error(msg); } else { cont->checkIntroduced(scoped->v); $$ = def; } } } } | { $$ = 0; } ; // ---------------------------------------------------------------------- implements // ---------------------------------------------------------------------- : ICE_IMPLEMENTS interface_list { $$ = $2; } | { $$ = new ClassListTok; } ; // ---------------------------------------------------------------------- class_exports // ---------------------------------------------------------------------- : meta_data class_export ';' class_exports { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); ContainedPtr contained = ContainedPtr::dynamicCast($2); if(contained && !metaData->v.empty()) { contained->setMetaData(metaData->v); } } | error ';' class_exports { } | meta_data class_export { unit->error("`;' missing after definition"); } | { } ; // ---------------------------------------------------------------------- data_member // ---------------------------------------------------------------------- : optional_type_id { OptionalDefTokPtr def = OptionalDefTokPtr::dynamicCast($1); ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); DataMemberPtr dm; if(cl) { dm = cl->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", ""); } StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); if(st) { dm = st->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", ""); } ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); if(ex) { dm = ex->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, 0, "", ""); } unit->currentContainer()->checkIntroduced(def->v.name, dm); $$ = dm; } | optional_type_id '=' const_initializer { OptionalDefTokPtr def = OptionalDefTokPtr::dynamicCast($1); ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($3); ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); DataMemberPtr dm; if(cl) { dm = cl->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value, value->v.valueAsString, value->v.valueAsLiteral); } StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); if(st) { dm = st->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value, value->v.valueAsString, value->v.valueAsLiteral); } ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); if(ex) { dm = ex->createDataMember(def->v.name, def->v.type, def->v.optional, def->v.tag, value->v.value, value->v.valueAsString, value->v.valueAsLiteral); } unit->currentContainer()->checkIntroduced(def->v.name, dm); $$ = dm; } | type keyword { TypePtr type = TypePtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { $$ = cl->createDataMember(name, type, false, 0, 0, "", ""); // Dummy } StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); if(st) { $$ = st->createDataMember(name, type, false, 0, 0, "", ""); // Dummy } ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); if(ex) { $$ = ex->createDataMember(name, type, false, 0, 0, "", ""); // Dummy } assert($$); unit->error("keyword `" + name + "' cannot be used as data member name"); } | type { TypePtr type = TypePtr::dynamicCast($1); ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { $$ = cl->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy } StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); if(st) { $$ = st->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy } ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); if(ex) { $$ = ex->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy } assert($$); unit->error("missing data member name"); } ; // ---------------------------------------------------------------------- struct_data_member // ---------------------------------------------------------------------- : type_id { TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1); StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); DataMemberPtr dm = st->createDataMember(ts->v.second, ts->v.first, false, -1, 0, "", ""); unit->currentContainer()->checkIntroduced(ts->v.second, dm); $$ = dm; } | type_id '=' const_initializer { TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($1); ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($3); StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); DataMemberPtr dm = st->createDataMember(ts->v.second, ts->v.first, false, -1, value->v.value, value->v.valueAsString, value->v.valueAsLiteral); unit->currentContainer()->checkIntroduced(ts->v.second, dm); $$ = dm; } | optional type_id { TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2); StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); $$ = st->createDataMember(ts->v.second, ts->v.first, false, 0, 0, "", ""); // Dummy assert($$); unit->error("optional data members not supported in struct"); } | optional type_id '=' const_initializer { TypeStringTokPtr ts = TypeStringTokPtr::dynamicCast($2); StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); $$ = st->createDataMember(ts->v.second, ts->v.first, false, 0, 0, "", ""); // Dummy assert($$); unit->error("optional data members not supported in struct"); } | type keyword { TypePtr type = TypePtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); $$ = st->createDataMember(name, type, false, 0, 0, "", ""); // Dummy assert($$); unit->error("keyword `" + name + "' cannot be used as data member name"); } | type { TypePtr type = TypePtr::dynamicCast($1); StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); assert(st); $$ = st->createDataMember(IceUtil::generateUUID(), type, false, 0, 0, "", ""); // Dummy assert($$); unit->error("missing data member name"); } ; // ---------------------------------------------------------------------- return_type // ---------------------------------------------------------------------- : optional type { OptionalDefTokPtr m = OptionalDefTokPtr::dynamicCast($1); m->v.type = TypePtr::dynamicCast($2); $$ = m; } | type { OptionalDefTokPtr m = new OptionalDefTok(); m->v.type = TypePtr::dynamicCast($1); m->v.optional = false; m->v.tag = -1; $$ = m; } | ICE_VOID { OptionalDefTokPtr m = new OptionalDefTok; m->v.optional = false; m->v.tag = -1; $$ = m; } ; // ---------------------------------------------------------------------- operation_preamble // ---------------------------------------------------------------------- : return_type ICE_IDENT_OP { OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag); if(op) { cl->checkIntroduced(name, op); unit->pushContainer(op); $$ = op; } else { $$ = 0; } } else { $$ = 0; } } | ICE_IDEMPOTENT return_type ICE_IDENT_OP { OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag, Operation::Idempotent); if(op) { cl->checkIntroduced(name, op); unit->pushContainer(op); $$ = op; } else { $$ = 0; } } else { $$ = 0; } } | return_type ICE_KEYWORD_OP { OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($1); string name = StringTokPtr::dynamicCast($2)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag); if(op) { unit->pushContainer(op); unit->error("keyword `" + name + "' cannot be used as operation name"); $$ = op; // Dummy } else { $$ = 0; } } else { $$ = 0; } } | ICE_IDEMPOTENT return_type ICE_KEYWORD_OP { OptionalDefTokPtr returnType = OptionalDefTokPtr::dynamicCast($2); string name = StringTokPtr::dynamicCast($3)->v; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); if(cl) { OperationPtr op = cl->createOperation(name, returnType->v.type, returnType->v.optional, returnType->v.tag, Operation::Idempotent); if(op) { unit->pushContainer(op); unit->error("keyword `" + name + "' cannot be used as operation name"); $$ = op; // Dummy } else { return 0; } } else { $$ = 0; } } ; // ---------------------------------------------------------------------- operation // ---------------------------------------------------------------------- : operation_preamble parameters ')' { if($1) { unit->popContainer(); $$ = $1; } else { $$ = 0; } } throws { OperationPtr op = OperationPtr::dynamicCast($4); ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5); assert(el); if(op) { op->setExceptionList(el->v); } } | operation_preamble error ')' { if($1) { unit->popContainer(); } yyerrok; } throws { OperationPtr op = OperationPtr::dynamicCast($4); ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5); assert(el); if(op) { op->setExceptionList(el->v); // Dummy } } ; // ---------------------------------------------------------------------- class_export // ---------------------------------------------------------------------- : data_member | operation ; // ---------------------------------------------------------------------- interface_id // ---------------------------------------------------------------------- : ICE_INTERFACE ICE_IDENTIFIER { $$ = $2; } | ICE_INTERFACE keyword { StringTokPtr ident = StringTokPtr::dynamicCast($2); unit->error("keyword `" + ident->v + "' cannot be used as interface name"); $$ = $2; // Dummy } ; // ---------------------------------------------------------------------- interface_decl // ---------------------------------------------------------------------- : local_qualifier interface_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ClassDeclPtr cl = cont->createClassDecl(ident->v, true, local->v); cont->checkIntroduced(ident->v, cl); $$ = cl; } ; // ---------------------------------------------------------------------- interface_def // ---------------------------------------------------------------------- : local_qualifier interface_id interface_extends { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); ClassListTokPtr bases = ClassListTokPtr::dynamicCast($3); ClassDefPtr cl = cont->createClassDef(ident->v, -1, true, bases->v, local->v); if(cl) { cont->checkIntroduced(ident->v, cl); unit->pushContainer(cl); $$ = cl; } else { $$ = 0; } } '{' interface_exports '}' { if($4) { unit->popContainer(); $$ = $4; } else { $$ = 0; } } ; // ---------------------------------------------------------------------- interface_list // ---------------------------------------------------------------------- : scoped_name ',' interface_list { ClassListTokPtr intfs = ClassListTokPtr::dynamicCast($3); StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); TypeList types = cont->lookupType(scoped->v); if(!types.empty()) { ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front()); if(!cl || !cl->isInterface()) { string msg = "`"; msg += scoped->v; msg += "' is not an interface"; unit->error(msg); } else { ClassDefPtr def = cl->definition(); if(!def) { string msg = "`"; msg += scoped->v; msg += "' has been declared but not defined"; unit->error(msg); } else { cont->checkIntroduced(scoped->v); intfs->v.push_front(def); } } } $$ = intfs; } | scoped_name { ClassListTokPtr intfs = new ClassListTok; StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); TypeList types = cont->lookupType(scoped->v); if(!types.empty()) { ClassDeclPtr cl = ClassDeclPtr::dynamicCast(types.front()); if(!cl || !cl->isInterface()) { string msg = "`"; msg += scoped->v; msg += "' is not an interface"; unit->error(msg); // $$ is a dummy } else { ClassDefPtr def = cl->definition(); if(!def) { string msg = "`"; msg += scoped->v; msg += "' has been declared but not defined"; unit->error(msg); // $$ is a dummy } else { cont->checkIntroduced(scoped->v); intfs->v.push_front(def); } } } $$ = intfs; } | ICE_OBJECT { unit->error("illegal inheritance from type Object"); $$ = new ClassListTok; // Dummy } ; // ---------------------------------------------------------------------- interface_extends // ---------------------------------------------------------------------- : ICE_EXTENDS interface_list { $$ = $2; } | { $$ = new ClassListTok; } ; // ---------------------------------------------------------------------- interface_exports // ---------------------------------------------------------------------- : meta_data interface_export ';' interface_exports { StringListTokPtr metaData = StringListTokPtr::dynamicCast($1); ContainedPtr contained = ContainedPtr::dynamicCast($2); if(contained && !metaData->v.empty()) { contained->setMetaData(metaData->v); } } | error ';' interface_exports { } | meta_data interface_export { unit->error("`;' missing after definition"); } | { } ; // ---------------------------------------------------------------------- interface_export // ---------------------------------------------------------------------- : operation ; // ---------------------------------------------------------------------- exception_list // ---------------------------------------------------------------------- : exception ',' exception_list { ExceptionPtr exception = ExceptionPtr::dynamicCast($1); ExceptionListTokPtr exceptionList = ExceptionListTokPtr::dynamicCast($3); exceptionList->v.push_front(exception); $$ = exceptionList; } | exception { ExceptionPtr exception = ExceptionPtr::dynamicCast($1); ExceptionListTokPtr exceptionList = new ExceptionListTok; exceptionList->v.push_front(exception); $$ = exceptionList; } ; // ---------------------------------------------------------------------- exception // ---------------------------------------------------------------------- : scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); ExceptionPtr exception = cont->lookupException(scoped->v); if(!exception) { exception = cont->createException(IceUtil::generateUUID(), 0, false, Dummy); // Dummy } cont->checkIntroduced(scoped->v, exception); $$ = exception; } | keyword { StringTokPtr ident = StringTokPtr::dynamicCast($1); unit->error("keyword `" + ident->v + "' cannot be used as exception name"); $$ = unit->currentContainer()->createException(IceUtil::generateUUID(), 0, false, Dummy); // Dummy } ; // ---------------------------------------------------------------------- sequence_def // ---------------------------------------------------------------------- : local_qualifier ICE_SEQUENCE '<' meta_data type '>' ICE_IDENTIFIER { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($7); StringListTokPtr metaData = StringListTokPtr::dynamicCast($4); TypePtr type = TypePtr::dynamicCast($5); ContainerPtr cont = unit->currentContainer(); $$ = cont->createSequence(ident->v, type, metaData->v, local->v); } | local_qualifier ICE_SEQUENCE '<' meta_data type '>' keyword { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($7); StringListTokPtr metaData = StringListTokPtr::dynamicCast($4); TypePtr type = TypePtr::dynamicCast($5); ContainerPtr cont = unit->currentContainer(); $$ = cont->createSequence(ident->v, type, metaData->v, local->v); // Dummy unit->error("keyword `" + ident->v + "' cannot be used as sequence name"); } ; // ---------------------------------------------------------------------- dictionary_def // ---------------------------------------------------------------------- : local_qualifier ICE_DICTIONARY '<' meta_data type ',' meta_data type '>' ICE_IDENTIFIER { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($10); StringListTokPtr keyMetaData = StringListTokPtr::dynamicCast($4); TypePtr keyType = TypePtr::dynamicCast($5); StringListTokPtr valueMetaData = StringListTokPtr::dynamicCast($7); TypePtr valueType = TypePtr::dynamicCast($8); ContainerPtr cont = unit->currentContainer(); $$ = cont->createDictionary(ident->v, keyType, keyMetaData->v, valueType, valueMetaData->v, local->v); } | local_qualifier ICE_DICTIONARY '<' meta_data type ',' meta_data type '>' keyword { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($10); StringListTokPtr keyMetaData = StringListTokPtr::dynamicCast($4); TypePtr keyType = TypePtr::dynamicCast($5); StringListTokPtr valueMetaData = StringListTokPtr::dynamicCast($7); TypePtr valueType = TypePtr::dynamicCast($8); ContainerPtr cont = unit->currentContainer(); $$ = cont->createDictionary(ident->v, keyType, keyMetaData->v, valueType, valueMetaData->v, local->v); // Dummy unit->error("keyword `" + ident->v + "' cannot be used as dictionary name"); } ; // ---------------------------------------------------------------------- enum_id // ---------------------------------------------------------------------- : ICE_ENUM ICE_IDENTIFIER { $$ = $2; } | ICE_ENUM keyword { StringTokPtr ident = StringTokPtr::dynamicCast($2); unit->error("keyword `" + ident->v + "' cannot be used as enumeration name"); $$ = $2; // Dummy } ; // ---------------------------------------------------------------------- enum_def // ---------------------------------------------------------------------- : local_qualifier enum_id { BoolTokPtr local = BoolTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); ContainerPtr cont = unit->currentContainer(); EnumPtr en = cont->createEnum(ident->v, local->v); cont->checkIntroduced(ident->v, en); $$ = en; } '{' enumerator_list '}' { EnumPtr en = EnumPtr::dynamicCast($3); if(en) { EnumeratorListTokPtr enumerators = EnumeratorListTokPtr::dynamicCast($5); if(enumerators->v.empty()) { unit->error("enum `" + en->name() + "' must have at least one enumerator"); } en->setEnumerators(enumerators->v); // Dummy } $$ = $3; } | local_qualifier ICE_ENUM '{' enumerator_list '}' { unit->error("missing enumeration name"); BoolTokPtr local = BoolTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); EnumPtr en = cont->createEnum(IceUtil::generateUUID(), local->v, Dummy); // Dummy EnumeratorListTokPtr enumerators = EnumeratorListTokPtr::dynamicCast($4); en->setEnumerators(enumerators->v); // Dummy $$ = en; } ; // ---------------------------------------------------------------------- enumerator_list // ---------------------------------------------------------------------- : enumerator ',' enumerator_list { EnumeratorListTokPtr ens = EnumeratorListTokPtr::dynamicCast($1); ens->v.splice(ens->v.end(), EnumeratorListTokPtr::dynamicCast($3)->v); $$ = ens; } | enumerator { } ; // ---------------------------------------------------------------------- enumerator // ---------------------------------------------------------------------- : ICE_IDENTIFIER { StringTokPtr ident = StringTokPtr::dynamicCast($1); EnumeratorListTokPtr ens = new EnumeratorListTok; ContainerPtr cont = unit->currentContainer(); EnumeratorPtr en = cont->createEnumerator(ident->v); if(en) { ens->v.push_front(en); } $$ = ens; } | ICE_IDENTIFIER '=' enumerator_initializer { StringTokPtr ident = StringTokPtr::dynamicCast($1); EnumeratorListTokPtr ens = new EnumeratorListTok; ContainerPtr cont = unit->currentContainer(); IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($3); if(intVal) { if(intVal->v < 0 || intVal->v > Int32Max) { unit->error("value for enumerator `" + ident->v + "' is out of range"); } else { EnumeratorPtr en = cont->createEnumerator(ident->v, static_cast(intVal->v)); if(en) { ens->v.push_front(en); } } } $$ = ens; } | keyword { StringTokPtr ident = StringTokPtr::dynamicCast($1); unit->error("keyword `" + ident->v + "' cannot be used as enumerator"); EnumeratorListTokPtr ens = new EnumeratorListTok; // Dummy $$ = ens; } | { EnumeratorListTokPtr ens = new EnumeratorListTok; $$ = ens; // Dummy } ; // ---------------------------------------------------------------------- enumerator_initializer // ---------------------------------------------------------------------- : ICE_INTEGER_LITERAL { $$ = $1; } | scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainedList cl = unit->currentContainer()->lookupContained(scoped->v); IntegerTokPtr tok; if(!cl.empty()) { ConstPtr constant = ConstPtr::dynamicCast(cl.front()); if(constant) { unit->currentContainer()->checkIntroduced(scoped->v, constant); BuiltinPtr b = BuiltinPtr::dynamicCast(constant->type()); if(b && (b->kind() == Builtin::KindByte || b->kind() == Builtin::KindShort || b->kind() == Builtin::KindInt || b->kind() == Builtin::KindLong)) { IceUtil::Int64 v; if(IceUtilInternal::stringToInt64(constant->value(), v)) { tok = new IntegerTok; tok->v = v; tok->literal = constant->value(); } } } } if(!tok) { string msg = "illegal initializer: `" + scoped->v + "' is not an integer constant"; unit->error(msg); // $$ is dummy } $$ = tok; } ; // ---------------------------------------------------------------------- out_qualifier // ---------------------------------------------------------------------- : ICE_OUT { BoolTokPtr out = new BoolTok; out->v = true; $$ = out; } | { BoolTokPtr out = new BoolTok; out->v = false; $$ = out; } ; // ---------------------------------------------------------------------- parameters // ---------------------------------------------------------------------- : // empty { } | out_qualifier meta_data optional_type_id { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1); OptionalDefTokPtr tsp = OptionalDefTokPtr::dynamicCast($3); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { ParamDeclPtr pd = op->createParamDecl(tsp->v.name, tsp->v.type, isOutParam->v, tsp->v.optional, tsp->v.tag); unit->currentContainer()->checkIntroduced(tsp->v.name, pd); StringListTokPtr metaData = StringListTokPtr::dynamicCast($2); if(!metaData->v.empty()) { pd->setMetaData(metaData->v); } } } | parameters ',' out_qualifier meta_data optional_type_id { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3); OptionalDefTokPtr tsp = OptionalDefTokPtr::dynamicCast($5); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { ParamDeclPtr pd = op->createParamDecl(tsp->v.name, tsp->v.type, isOutParam->v, tsp->v.optional, tsp->v.tag); unit->currentContainer()->checkIntroduced(tsp->v.name, pd); StringListTokPtr metaData = StringListTokPtr::dynamicCast($4); if(!metaData->v.empty()) { pd->setMetaData(metaData->v); } } } | out_qualifier meta_data type keyword { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1); TypePtr type = TypePtr::dynamicCast($3); StringTokPtr ident = StringTokPtr::dynamicCast($4); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { op->createParamDecl(ident->v, type, isOutParam->v, false, 0); // Dummy unit->error("keyword `" + ident->v + "' cannot be used as parameter name"); } } | parameters ',' out_qualifier meta_data type keyword { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3); TypePtr type = TypePtr::dynamicCast($5); StringTokPtr ident = StringTokPtr::dynamicCast($6); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { op->createParamDecl(ident->v, type, isOutParam->v, false, 0); // Dummy unit->error("keyword `" + ident->v + "' cannot be used as parameter name"); } } | out_qualifier meta_data type { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($1); TypePtr type = TypePtr::dynamicCast($3); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { op->createParamDecl(IceUtil::generateUUID(), type, isOutParam->v, false, 0); // Dummy unit->error("missing parameter name"); } } | parameters ',' out_qualifier meta_data type { BoolTokPtr isOutParam = BoolTokPtr::dynamicCast($3); TypePtr type = TypePtr::dynamicCast($5); OperationPtr op = OperationPtr::dynamicCast(unit->currentContainer()); if(op) { op->createParamDecl(IceUtil::generateUUID(), type, isOutParam->v, false, 0); // Dummy unit->error("missing parameter name"); } } ; // ---------------------------------------------------------------------- throws // ---------------------------------------------------------------------- : ICE_THROWS exception_list { $$ = $2; } | { $$ = new ExceptionListTok; } ; // ---------------------------------------------------------------------- scoped_name // ---------------------------------------------------------------------- : ICE_IDENTIFIER { } | ICE_SCOPE_DELIMITER ICE_IDENTIFIER { StringTokPtr ident = StringTokPtr::dynamicCast($2); ident->v = "::" + ident->v; $$ = ident; } | scoped_name ICE_SCOPE_DELIMITER ICE_IDENTIFIER { StringTokPtr scoped = StringTokPtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($3); scoped->v += "::"; scoped->v += ident->v; $$ = scoped; } ; // ---------------------------------------------------------------------- type // ---------------------------------------------------------------------- : ICE_BYTE { $$ = unit->builtin(Builtin::KindByte); } | ICE_BOOL { $$ = unit->builtin(Builtin::KindBool); } | ICE_SHORT { $$ = unit->builtin(Builtin::KindShort); } | ICE_INT { $$ = unit->builtin(Builtin::KindInt); } | ICE_LONG { $$ = unit->builtin(Builtin::KindLong); } | ICE_FLOAT { $$ = unit->builtin(Builtin::KindFloat); } | ICE_DOUBLE { $$ = unit->builtin(Builtin::KindDouble); } | ICE_STRING { $$ = unit->builtin(Builtin::KindString); } | ICE_OBJECT { $$ = unit->builtin(Builtin::KindObject); } | ICE_OBJECT '*' { $$ = unit->builtin(Builtin::KindObjectProxy); } | ICE_LOCAL_OBJECT { $$ = unit->builtin(Builtin::KindLocalObject); } | scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); if(cont) { TypeList types = cont->lookupType(scoped->v); if(types.empty()) { YYERROR; // Can't continue, jump to next yyerrok } cont->checkIntroduced(scoped->v); $$ = types.front(); } else { $$ = 0; } } | scoped_name '*' { StringTokPtr scoped = StringTokPtr::dynamicCast($1); ContainerPtr cont = unit->currentContainer(); if(cont) { TypeList types = cont->lookupType(scoped->v); if(types.empty()) { YYERROR; // Can't continue, jump to next yyerrok } for(TypeList::iterator p = types.begin(); p != types.end(); ++p) { ClassDeclPtr cl = ClassDeclPtr::dynamicCast(*p); if(!cl) { string msg = "`"; msg += scoped->v; msg += "' must be class or interface"; unit->error(msg); YYERROR; // Can't continue, jump to next yyerrok } cont->checkIntroduced(scoped->v); if(cl->isLocal()) { unit->error("cannot create proxy for " + cl->kindOf() + " `" + cl->name() + "'"); // $$ is dummy } *p = new Proxy(cl); } $$ = types.front(); } else { $$ = 0; } } ; // ---------------------------------------------------------------------- string_literal // ---------------------------------------------------------------------- : ICE_STRING_LITERAL string_literal // Adjacent string literals are concatenated { StringTokPtr str1 = StringTokPtr::dynamicCast($1); StringTokPtr str2 = StringTokPtr::dynamicCast($2); str1->v += str2->v; } | ICE_STRING_LITERAL { } ; // ---------------------------------------------------------------------- string_list // ---------------------------------------------------------------------- : string_list ',' string_literal { StringTokPtr str = StringTokPtr::dynamicCast($3); StringListTokPtr stringList = StringListTokPtr::dynamicCast($1); stringList->v.push_back(str->v); $$ = stringList; } | string_literal { StringTokPtr str = StringTokPtr::dynamicCast($1); StringListTokPtr stringList = new StringListTok; stringList->v.push_back(str->v); $$ = stringList; } ; // ---------------------------------------------------------------------- local_qualifier // ---------------------------------------------------------------------- : ICE_LOCAL { BoolTokPtr local = new BoolTok; local->v = true; $$ = local; } | { BoolTokPtr local = new BoolTok; local->v = false; $$ = local; } ; // ---------------------------------------------------------------------- const_initializer // ---------------------------------------------------------------------- : ICE_INTEGER_LITERAL { BuiltinPtr type = unit->builtin(Builtin::KindLong); IntegerTokPtr intVal = IntegerTokPtr::dynamicCast($1); ostringstream sstr; sstr << intVal->v; ConstDefTokPtr def = new ConstDefTok; def->v.type = type; def->v.value = type; def->v.valueAsString = sstr.str(); def->v.valueAsLiteral = intVal->literal; $$ = def; } | ICE_FLOATING_POINT_LITERAL { BuiltinPtr type = unit->builtin(Builtin::KindDouble); FloatingTokPtr floatVal = FloatingTokPtr::dynamicCast($1); ostringstream sstr; sstr << floatVal->v; ConstDefTokPtr def = new ConstDefTok; def->v.type = type; def->v.value = type; def->v.valueAsString = sstr.str(); def->v.valueAsLiteral = floatVal->literal; $$ = def; } | scoped_name { StringTokPtr scoped = StringTokPtr::dynamicCast($1); ConstDefTokPtr def = new ConstDefTok; ContainedList cl = unit->currentContainer()->lookupContained(scoped->v); if(cl.empty()) { def->v.type = TypePtr(0); def->v.value = SyntaxTreeBasePtr(0); def->v.valueAsString = scoped->v; def->v.valueAsLiteral = scoped->v; } else { EnumeratorPtr enumerator = EnumeratorPtr::dynamicCast(cl.front()); ConstPtr constant = ConstPtr::dynamicCast(cl.front()); if(enumerator) { unit->currentContainer()->checkIntroduced(scoped->v, enumerator); def->v.type = enumerator->type(); def->v.value = enumerator; def->v.valueAsString = scoped->v; def->v.valueAsLiteral = scoped->v; } else if(constant) { unit->currentContainer()->checkIntroduced(scoped->v, constant); def->v.value = constant; def->v.valueAsString = constant->value(); def->v.valueAsLiteral = constant->value(); } else { string msg = "illegal initializer: `" + scoped->v + "' is a"; static const string vowels = "aeiou"; string kindOf = cl.front()->kindOf(); if(vowels.find_first_of(kindOf[0]) != string::npos) { msg += "n"; } msg += " " + kindOf; unit->error(msg); // $$ is dummy } } $$ = def; } | ICE_STRING_LITERAL { BuiltinPtr type = unit->builtin(Builtin::KindString); StringTokPtr literal = StringTokPtr::dynamicCast($1); ConstDefTokPtr def = new ConstDefTok; def->v.type = type; def->v.value = type; def->v.valueAsString = literal->v; def->v.valueAsLiteral = literal->literal; $$ = def; } | ICE_FALSE { BuiltinPtr type = unit->builtin(Builtin::KindBool); StringTokPtr literal = StringTokPtr::dynamicCast($1); ConstDefTokPtr def = new ConstDefTok; def->v.type = type; def->v.value = type; def->v.valueAsString = "false"; def->v.valueAsLiteral = "false"; $$ = def; } | ICE_TRUE { BuiltinPtr type = unit->builtin(Builtin::KindBool); StringTokPtr literal = StringTokPtr::dynamicCast($1); ConstDefTokPtr def = new ConstDefTok; def->v.type = type; def->v.value = type; def->v.valueAsString = "true"; def->v.valueAsLiteral = "true"; $$ = def; } ; // ---------------------------------------------------------------------- const_def // ---------------------------------------------------------------------- : ICE_CONST meta_data type ICE_IDENTIFIER '=' const_initializer { StringListTokPtr metaData = StringListTokPtr::dynamicCast($2); TypePtr const_type = TypePtr::dynamicCast($3); StringTokPtr ident = StringTokPtr::dynamicCast($4); ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($6); $$ = unit->currentContainer()->createConst(ident->v, const_type, metaData->v, value->v.value, value->v.valueAsString, value->v.valueAsLiteral); } | ICE_CONST meta_data type '=' const_initializer { StringListTokPtr metaData = StringListTokPtr::dynamicCast($2); TypePtr const_type = TypePtr::dynamicCast($3); ConstDefTokPtr value = ConstDefTokPtr::dynamicCast($5); unit->error("missing constant name"); $$ = unit->currentContainer()->createConst(IceUtil::generateUUID(), const_type, metaData->v, value->v.value, value->v.valueAsString, value->v.valueAsLiteral, Dummy); // Dummy } ; // ---------------------------------------------------------------------- keyword // ---------------------------------------------------------------------- : ICE_MODULE { } | ICE_CLASS { } | ICE_INTERFACE { } | ICE_EXCEPTION { } | ICE_STRUCT { } | ICE_SEQUENCE { } | ICE_DICTIONARY { } | ICE_ENUM { } | ICE_OUT { } | ICE_EXTENDS { } | ICE_IMPLEMENTS { } | ICE_THROWS { } | ICE_VOID { } | ICE_BYTE { } | ICE_BOOL { } | ICE_SHORT { } | ICE_INT { } | ICE_LONG { } | ICE_FLOAT { } | ICE_DOUBLE { } | ICE_STRING { } | ICE_OBJECT { } | ICE_LOCAL_OBJECT { } | ICE_LOCAL { } | ICE_CONST { } | ICE_FALSE { } | ICE_TRUE { } | ICE_IDEMPOTENT { } | ICE_OPTIONAL { } ; %%