summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2002-08-20 04:43:18 +0000
committerMichi Henning <michi@zeroc.com>2002-08-20 04:43:18 +0000
commit1911e13823713c6569c8a04d0c69b6d85e58fb4c (patch)
treee415a4d7946171f6e15fee795ea39f2eabf52f27 /cpp/src
parentnonmutating => isNonmutating (diff)
downloadice-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.y355
-rw-r--r--cpp/src/Slice/Scanner.l93
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;
+}
+
}