diff options
author | Michi Henning <michi@zeroc.com> | 2002-08-20 04:43:18 +0000 |
---|---|---|
committer | Michi Henning <michi@zeroc.com> | 2002-08-20 04:43:18 +0000 |
commit | 1911e13823713c6569c8a04d0c69b6d85e58fb4c (patch) | |
tree | e415a4d7946171f6e15fee795ea39f2eabf52f27 /cpp/src | |
parent | nonmutating => isNonmutating (diff) | |
download | ice-1911e13823713c6569c8a04d0c69b6d85e58fb4c.tar.bz2 ice-1911e13823713c6569c8a04d0c69b6d85e58fb4c.tar.xz ice-1911e13823713c6569c8a04d0c69b6d85e58fb4c.zip |
Reworked parser for nonmutating keyword. Nonmutating is now only
permissible for operations, as it should be.
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/Grammar.y | 355 | ||||
-rw-r--r-- | cpp/src/Slice/Scanner.l | 93 |
2 files changed, 217 insertions, 231 deletions
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y index 2ed33e281d9..49774b2ef9d 100644 --- a/cpp/src/Slice/Grammar.y +++ b/cpp/src/Slice/Grammar.y @@ -33,14 +33,6 @@ yyerror(const char* s) %pure_parser // -// Need precedence declarations to avoid shift/reduce conflicts for nonmutating qualifier. -// By default, we'd get a shift, but we want a reduce. (Note: excess line length is -// necessary here because bison doesn't recognize backslash-newline as a continuation sequence.) -// -%nonassoc ICE_BYTE ICE_BOOL ICE_SHORT ICE_INT ICE_LONG ICE_FLOAT ICE_DOUBLE ICE_STRING ICE_OBJECT ICE_LOCAL_OBJECT ICE_SCOPE_DELIMITER ICE_IDENTIFIER -%nonassoc ICE_NONMUTATING - -// // 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. @@ -82,6 +74,8 @@ yyerror(const char* s) %token ICE_STRING_LITERAL %token ICE_INTEGER_LITERAL %token ICE_FLOATING_POINT_LITERAL +%token ICE_IDENT_OP +%token ICE_KEYWORD_OP %% @@ -291,37 +285,25 @@ exception_exports ; // ---------------------------------------------------------------------- -exception_export +type_id // ---------------------------------------------------------------------- -: type_id -{ - TypeStringTokPtr tsp = TypeStringTokPtr::dynamicCast($1); - TypePtr type = tsp->v.first; - string ident = tsp->v.second; - ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); - assert(ex); - DataMemberPtr dm = ex->createDataMember(ident, type); - unit->currentContainer()->checkIntroduced(ident, dm); - $$ = dm; -} -| type keyword +: type ICE_IDENTIFIER { TypePtr type = TypePtr::dynamicCast($1); StringTokPtr ident = StringTokPtr::dynamicCast($2); - ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); - unit->error("keyword `" + ident->v + "' cannot be used as exception name"); - $$ = ex->createDataMember(ident->v, type); -} -| type -{ - TypePtr type = TypePtr::dynamicCast($1); - ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); - unit->error("missing data member name"); - $$ = ex->createDataMember("", type); + TypeStringTokPtr typestring = new TypeStringTok; + typestring->v = make_pair(type, ident->v); + $$ = typestring; } ; // ---------------------------------------------------------------------- +exception_export +// ---------------------------------------------------------------------- +: data_member +; + +// ---------------------------------------------------------------------- struct_id // ---------------------------------------------------------------------- : ICE_STRUCT ICE_IDENTIFIER @@ -407,34 +389,7 @@ struct_exports // ---------------------------------------------------------------------- struct_export // ---------------------------------------------------------------------- -: type_id -{ - TypeStringTokPtr tsp = TypeStringTokPtr::dynamicCast($1); - TypePtr type = tsp->v.first; - string ident = tsp->v.second; - StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); - assert(st); - DataMemberPtr dm = st->createDataMember(ident, type); - unit->currentContainer()->checkIntroduced(ident, dm); - $$ = dm; -} -| type keyword -{ - TypePtr type = TypePtr::dynamicCast($1); - StringTokPtr ident = StringTokPtr::dynamicCast($2); - StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); - assert(st); - unit->error("keyword `" + ident->v + "' cannot be used as data member name"); - $$ = st->createDataMember(ident->v, type); -} -| type -{ - TypePtr type = TypePtr::dynamicCast($1); - StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); - assert(st); - unit->error("missing data member name"); - $$ = st->createDataMember("", type); -} +: data_member ; // ---------------------------------------------------------------------- @@ -576,66 +531,175 @@ class_exports ; // ---------------------------------------------------------------------- -class_export +data_member // ---------------------------------------------------------------------- -: nonmutating_qualifier type_id +: type_id { - TypeStringTokPtr tsp = TypeStringTokPtr::dynamicCast($2); - TypePtr type = tsp->v.first; - string ident = tsp->v.second; + TypePtr type = TypeStringTokPtr::dynamicCast($1)->v.first; + string name = TypeStringTokPtr::dynamicCast($1)->v.second; ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - DataMemberPtr dm = cl->createDataMember(ident, type); - cl->checkIntroduced(ident, dm); + DataMemberPtr dm; + if(cl) + { + dm = cl->createDataMember(name, type); + } + StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); + if(st) + { + dm = st->createDataMember(name, type); + } + ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); + if(ex) + { + dm = ex->createDataMember(name, type); + } + unit->currentContainer()->checkIntroduced(name, dm); $$ = dm; } -| operation_preamble '(' parameters ')' +| 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); + } + StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); + if(st) + { + $$ = st->createDataMember(name, type); + } + ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); + if(ex) + { + $$ = ex->createDataMember(name, type); + } + 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); + } + StructPtr st = StructPtr::dynamicCast(unit->currentContainer()); + if(st) + { + $$ = st->createDataMember(IceUtil::generateUUID(), type); + } + ExceptionPtr ex = ExceptionPtr::dynamicCast(unit->currentContainer()); + if(ex) + { + $$ = ex->createDataMember(IceUtil::generateUUID(), type); + } + assert($$); + unit->error("missing data member name"); +} +; + +// ---------------------------------------------------------------------- +return_type +// ---------------------------------------------------------------------- +: type +| ICE_VOID +{ + $$ = 0; +} +; + +// ---------------------------------------------------------------------- +operation_preamble +// ---------------------------------------------------------------------- +: return_type ICE_IDENT_OP +{ + TypePtr returnType = TypePtr::dynamicCast($1); + string name = StringTokPtr::dynamicCast($2)->v; + ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); + assert(cl); + OperationPtr op = cl->createOperation(name, returnType, false); + cl->checkIntroduced(name, op); + unit->pushContainer(op); + $$ = op; +} +| ICE_NONMUTATING return_type ICE_IDENT_OP +{ + TypePtr returnType = TypePtr::dynamicCast($2); + string name = StringTokPtr::dynamicCast($3)->v; + ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); + assert(cl); + OperationPtr op = cl->createOperation(name, returnType, true); + cl->checkIntroduced(name, op); + unit->pushContainer(op); + $$ = op; +} +| return_type ICE_KEYWORD_OP +{ + TypePtr returnType = TypePtr::dynamicCast($1); + string name = StringTokPtr::dynamicCast($2)->v; + ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); + assert(cl); + OperationPtr op = cl->createOperation(name, returnType, false); + unit->pushContainer(op); + unit->error("keyword `" + name + "' cannot be used as operation name"); + $$ = op; +} +| ICE_NONMUTATING return_type ICE_KEYWORD_OP +{ + TypePtr returnType = TypePtr::dynamicCast($2); + string name = StringTokPtr::dynamicCast($3)->v; + ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); + assert(cl); + OperationPtr op = cl->createOperation(name, returnType, true); + unit->pushContainer(op); + unit->error("keyword `" + name + "' cannot be used as operation name"); + $$ = op; +} +; + +// ---------------------------------------------------------------------- +operation +// ---------------------------------------------------------------------- +: operation_preamble parameters ')' { unit->popContainer(); $$ = $1; } throws { - OperationPtr op = OperationPtr::dynamicCast($5); - ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($6); + OperationPtr op = OperationPtr::dynamicCast($4); + ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5); assert(el); if(op) { op->setExceptionList(el->v); } } -| operation_preamble '(' error ')' +| operation_preamble error ')' { unit->popContainer(); yyerrok; } throws { - OperationPtr op = OperationPtr::dynamicCast($5); - ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($6); + OperationPtr op = OperationPtr::dynamicCast($4); + ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($5); assert(el); if(op) { op->setExceptionList(el->v); } } -| nonmutating_qualifier type keyword -{ - TypePtr type = TypePtr::dynamicCast($2); - StringTokPtr ident = StringTokPtr::dynamicCast($3); - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - unit->error("keyword `" + ident->v + "' cannot be used as data member name"); - $$ = cl->createDataMember(ident->v, type); -} -| nonmutating_qualifier type -{ - TypePtr type = TypePtr::dynamicCast($2); - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - unit->error("missing data member name"); - $$ = cl->createDataMember("", type); -} +; + +// ---------------------------------------------------------------------- +class_export +// ---------------------------------------------------------------------- +: data_member +| operation ; // ---------------------------------------------------------------------- @@ -807,36 +871,7 @@ interface_exports // ---------------------------------------------------------------------- interface_export // ---------------------------------------------------------------------- -: operation_preamble '(' parameters ')' -{ - unit->popContainer(); - $$ = $1; -} -throws -{ - OperationPtr op = OperationPtr::dynamicCast($5); - ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($6); - assert(el); - if(op) - { - op->setExceptionList(el->v); - } -} -| operation_preamble '(' error ')' -{ - unit->popContainer(); - yyerrok; -} -throws -{ - OperationPtr op = OperationPtr::dynamicCast($5); - ExceptionListTokPtr el = ExceptionListTokPtr::dynamicCast($6); - assert(el); - if(op) - { - op->setExceptionList(el->v); - } -} +: operation ; // ---------------------------------------------------------------------- @@ -1014,86 +1049,6 @@ enumerator ; // ---------------------------------------------------------------------- -nonmutating_qualifier -// ---------------------------------------------------------------------- -: ICE_NONMUTATING -{ - BoolTokPtr nonmutating = new BoolTok; - nonmutating->v = true; - $$ = nonmutating; -} -| %prec ICE_NONMUTATING -{ - BoolTokPtr nonmutating = new BoolTok; - nonmutating->v = false; - $$ = nonmutating; -} -; - -// ---------------------------------------------------------------------- -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; -} -; - -// ---------------------------------------------------------------------- -operation_preamble -// ---------------------------------------------------------------------- -: nonmutating_qualifier type_id -{ - BoolTokPtr nonmutating = BoolTokPtr::dynamicCast($1); - TypeStringTokPtr tsp = TypeStringTokPtr::dynamicCast($2); - TypePtr returnType = tsp->v.first; - string name = tsp->v.second; - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(name, returnType, nonmutating->v); - cl->checkIntroduced(name, op); - unit->pushContainer(op); - $$ = op; -} -| nonmutating_qualifier ICE_VOID ICE_IDENTIFIER -{ - BoolTokPtr nonmutating = BoolTokPtr::dynamicCast($1); - StringTokPtr ident = StringTokPtr::dynamicCast($3); - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - OperationPtr op = cl->createOperation(ident->v, 0, nonmutating->v); - unit->currentContainer()->checkIntroduced(ident->v, op); - unit->pushContainer(op); - $$ = op; -} -| nonmutating_qualifier type keyword -{ - TypePtr returnType = TypePtr::dynamicCast($2); - StringTokPtr ident = StringTokPtr::dynamicCast($3); - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - unit->error("keyword `" + ident->v + "' cannot be used as operation name"); - OperationPtr op = cl->createOperation(ident->v, returnType, false); - unit->pushContainer(op); - $$ = op; -} -| nonmutating_qualifier ICE_VOID keyword -{ - StringTokPtr ident = StringTokPtr::dynamicCast($3); - ClassDefPtr cl = ClassDefPtr::dynamicCast(unit->currentContainer()); - assert(cl); - unit->error("keyword `" + ident->v + "' cannot be used as operation name"); - OperationPtr op = cl->createOperation(ident->v, 0, false); - unit->pushContainer(op); - $$ = op; -} -; - -// ---------------------------------------------------------------------- out_qualifier // ---------------------------------------------------------------------- : ICE_OUT diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l index aefa6fd16d8..2e0074b6271 100644 --- a/cpp/src/Slice/Scanner.l +++ b/cpp/src/Slice/Scanner.l @@ -30,6 +30,8 @@ typedef std::map<std::string, int, Slice::CICompare> StringTokenMap; static StringTokenMap keywordMap; void initScanner(); +void checkIdentifier(const string&); +int checkKeyword(string&); } @@ -122,44 +124,25 @@ floating_literal (({fractional_constant}{exponent_part}?)|([[:digit:]]+{exponent return ICE_SCOPE_DELIMITER; } -{identifier} { +{identifier}[[:space:]]*"(" { StringTokPtr ident = new StringTok; ident->v = *yytext == '\\' ? yytext + 1 : yytext; + ident->v.erase(ident->v.find_first_of(" \t\v\n\r\f(")); *yylvalp = ident; - - if(ident->v.find('_') != string::npos) - { - unit->warning("illegal underscore in identifier `" + ident->v + "'"); - } - - static const string suffixBlacklist[] = { "Helper", "Holder", "Operations", "Prx", "Ptr" }; - for(size_t i = 0; i < sizeof(suffixBlacklist) / sizeof(*suffixBlacklist); ++i) - { - if(ident->v.find(suffixBlacklist[i], ident->v.size() - suffixBlacklist[i].size()) != string::npos) - { - unit->error("illegal identifier `" + ident->v + "': `" + suffixBlacklist[i] + "' suffix is reserved"); - } - } - + checkIdentifier(ident->v); if(*yytext == '\\') { - return ICE_IDENTIFIER; + return ICE_IDENT_OP; } + return checkKeyword(ident->v) == ICE_IDENTIFIER ? ICE_IDENT_OP : ICE_KEYWORD_OP; +} - StringTokenMap::const_iterator pos = keywordMap.find(ident->v); - if(pos != keywordMap.end()) - { - if(pos->first != ident->v) - { - string msg; - msg = "illegal identifier: `" + ident->v + "' differs from keyword `"; - msg += pos->first + "' only in capitalization"; - unit->error(msg); - ident->v = pos->first; - } - return pos->second; - } - return ICE_IDENTIFIER; +{identifier} { + StringTokPtr ident = new StringTok; + ident->v = *yytext == '\\' ? yytext + 1 : yytext; + *yylvalp = ident; + checkIdentifier(ident->v); + return *yytext == '\\' ? ICE_IDENTIFIER : checkKeyword(ident->v); } \" { @@ -406,4 +389,52 @@ initScanner() keywordMap["nonmutating"] = ICE_NONMUTATING; } +// +// Check if an identifier is well-formed. +// + +void +checkIdentifier(const string& id) +{ + if(id.find('_') != string::npos) + { + unit->warning("illegal underscore in identifier `" + id + "'"); + } + + static const string suffixBlacklist[] = { "Helper", "Holder", "Operations", "Prx", "Ptr" }; + for(size_t i = 0; i < sizeof(suffixBlacklist) / sizeof(*suffixBlacklist); ++i) + { + if(id.find(suffixBlacklist[i], id.size() - suffixBlacklist[i].size()) != string::npos) + { + unit->error("illegal identifier `" + id + "': `" + suffixBlacklist[i] + "' suffix is reserved"); + } + } +} + +// +// Check if an identifier looks like a keyword. +// If the identifier is a keyword, return the +// corresponding keyword token; otherwise, return +// an identifier token. +// + +int +checkKeyword(string& id) +{ + StringTokenMap::const_iterator pos = keywordMap.find(id); + if(pos != keywordMap.end()) + { + if(pos->first != id) + { + string msg; + msg = "illegal identifier: `" + id + "' differs from keyword `"; + msg += pos->first + "' only in capitalization"; + unit->error(msg); + id = pos->first; + } + return pos->second; + } + return ICE_IDENTIFIER; +} + } |