summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2002-06-19 06:38:05 +0000
committerMichi Henning <michi@zeroc.com>2002-06-19 06:38:05 +0000
commitac5baaf4675325375d05f2079f2f0678c6e86fd8 (patch)
treebb2526a6c6593f1125196d6e5ff3a1f9cf7b784d /cpp/src
parentfile ActivatorI.cpp was initially added on branch location. (diff)
downloadice-ac5baaf4675325375d05f2079f2f0678c6e86fd8.tar.bz2
ice-ac5baaf4675325375d05f2079f2f0678c6e86fd8.tar.xz
ice-ac5baaf4675325375d05f2079f2f0678c6e86fd8.zip
Changed the grammar for out parameters to deprecate the semicolon syntax
and use an "out" keyword instead. The old syntax still works, but now prints a warning. Fixed up all the test cases that got broken by this and add a new test case for out-of-order in and out parameters. Refactored the grammar somewhat because, initially, out params added something like 50 shift/reduce conflicts. One shift/reduce conflict remains, caused by the addition of ICE_OUT to the last production in Grammar.y. We could avoid the conflict by removing ICE_OUT from that production, but then we wouldn't catch other errors anymore, such as an attempt to use "out" as the name of an operation or interface. I've added a warning to the Makefile to expect 1 shift/reduce conflict when Grammar.y is rebuilt.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Slice/Grammar.y88
-rw-r--r--cpp/src/Slice/GrammarUtil.h14
-rw-r--r--cpp/src/Slice/Makefile1
-rw-r--r--cpp/src/Slice/Parser.cpp9
-rw-r--r--cpp/src/Slice/Scanner.l8
5 files changed, 97 insertions, 23 deletions
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index 58abb4fc474..7fb37c3af41 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -43,6 +43,7 @@ yyerror(const char* s)
%token ICE_SEQUENCE
%token ICE_DICTIONARY
%token ICE_ENUM
+%token ICE_OUT
%token ICE_EXTENDS
%token ICE_IMPLEMENTS
%token ICE_THROWS
@@ -819,43 +820,60 @@ operation
;
// ----------------------------------------------------------------------
-parameters
+param_decl
// ----------------------------------------------------------------------
-: type ICE_IDENTIFIER ',' parameters
+: type ICE_IDENTIFIER
{
TypePtr type = TypePtr::dynamicCast($1);
StringTokPtr ident = StringTokPtr::dynamicCast($2);
- TypeStringListTokPtr parms = TypeStringListTokPtr::dynamicCast($4);
- parms->v.push_front(make_pair(type, ident->v));
- $$ = parms;
+ TypeStringTokPtr typestring = new TypeStringTok;
+ typestring->v = make_pair(type, ident->v);
+ $$ = typestring;
}
-| type ICE_IDENTIFIER
+| type keyword
+{
+ unit->error("keyword cannot be used as a parameter name");
+ $$ = new TypeStringTok;
+}
+| type
{
TypePtr type = TypePtr::dynamicCast($1);
- StringTokPtr ident = StringTokPtr::dynamicCast($2);
- TypeStringListTokPtr parms = new TypeStringListTok;
- parms->v.push_front(make_pair(type, ident->v));
- $$ = parms;
+ unit->error("missing parameter name");
+ $$ = new TypeStringTok;
}
-| type ',' parameters
+;
+
+// ----------------------------------------------------------------------
+out_param_decl
+// ----------------------------------------------------------------------
+: ICE_OUT param_decl
{
- unit->error("missing declarator");
- $$ = $3
+ $$ = $2;
}
-| type
+|
+out_param_decl ',' param_decl
{
- unit->error("missing declarator");
- $$ = new TypeStringListTok;
+ unit->error("in parameters cannot follow out parameters");
+ $$ = $1;
}
-| type keyword ',' parameters
+;
+
+// ----------------------------------------------------------------------
+parameters
+// ----------------------------------------------------------------------
+: param_decl ',' parameters
{
- unit->error("keyword cannot be used as declarator");
- $$ = $4
+ TypeStringListTokPtr parms = TypeStringListTokPtr::dynamicCast($3);
+ TypeStringTokPtr typestring = TypeStringTokPtr::dynamicCast($1);
+ parms->v.push_front(typestring->v);
+ $$ = parms;
}
-| type keyword
+| param_decl
{
- unit->error("keyword cannot be used as declarator");
- $$ = new TypeStringListTok;
+ TypeStringTokPtr typestring = TypeStringTokPtr::dynamicCast($1);
+ TypeStringListTokPtr parms = new TypeStringListTok;
+ parms->v.push_front(typestring->v);
+ $$ = parms;
}
|
{
@@ -866,10 +884,33 @@ parameters
// ----------------------------------------------------------------------
output_parameters
// ----------------------------------------------------------------------
+
+//
+// TODO: remove the first rule before releasing stable_39 -- the syntax
+// for out parameters has changed to use the out keyword, and the
+// semicolon syntax is deprecated for stable_38, to be removed with
+// stable_39.
+//
: ';' parameters
{
+ unit->warning("Deprecated use of semicolon to indicate out parameters");
+ unit->warning("Use the out keyword instead");
$$ = $2
}
+| out_param_decl ',' output_parameters
+{
+ TypeStringListTokPtr parms = TypeStringListTokPtr::dynamicCast($3);
+ TypeStringTokPtr typestring = TypeStringTokPtr::dynamicCast($1);
+ parms->v.push_front(typestring->v);
+ $$ = parms;
+}
+| out_param_decl
+{
+ TypeStringTokPtr typestring = TypeStringTokPtr::dynamicCast($1);
+ TypeStringListTokPtr parms = new TypeStringListTok;
+ parms->v.push_front(typestring->v);
+ $$ = parms;
+}
|
{
$$ = new TypeStringListTok;
@@ -1126,6 +1167,9 @@ keyword
| ICE_ENUM
{
}
+| ICE_OUT
+{
+}
;
%%
diff --git a/cpp/src/Slice/GrammarUtil.h b/cpp/src/Slice/GrammarUtil.h
index 3d64d605fbd..0d510e7e3d3 100644
--- a/cpp/src/Slice/GrammarUtil.h
+++ b/cpp/src/Slice/GrammarUtil.h
@@ -17,6 +17,7 @@ namespace Slice
{
class StringTok;
+class TypeStringTok;
class TypeStringListTok;
class StringListTok;
class BoolTok;
@@ -25,6 +26,7 @@ class ClassListTok;
class EnumeratorListTok;
typedef ::IceUtil::Handle<StringTok> StringTokPtr;
+typedef ::IceUtil::Handle<TypeStringTok> TypeStringTokPtr;
typedef ::IceUtil::Handle<TypeStringListTok> TypeStringListTokPtr;
typedef ::IceUtil::Handle<StringListTok> StringListTokPtr;
typedef ::IceUtil::Handle<BoolTok> BoolTokPtr;
@@ -45,6 +47,18 @@ public:
};
// ----------------------------------------------------------------------
+// TypeStringTok
+// ----------------------------------------------------------------------
+
+class SLICE_API TypeStringTok : public GrammarBase
+{
+public:
+
+ TypeStringTok() { }
+ TypeString v;
+};
+
+// ----------------------------------------------------------------------
// TypeStringListTok
// ----------------------------------------------------------------------
diff --git a/cpp/src/Slice/Makefile b/cpp/src/Slice/Makefile
index a9ada1884c5..cbb7f7e2cf0 100644
--- a/cpp/src/Slice/Makefile
+++ b/cpp/src/Slice/Makefile
@@ -39,6 +39,7 @@ $(NAME): $(VERSIONED_NAME)
ln -s $(VERSIONED_BASE) $@
Grammar.cpp Grammar.h: Grammar.y
+ @echo "Expect 1 shift/reduce conflict"
bison -dvt Grammar.y
rm -f Grammar.cpp ; mv Grammar.tab.c Grammar.cpp
rm -f Grammar.h ; mv Grammar.tab.h Grammar.h
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index cea765dc172..8fd318910e1 100644
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -1352,7 +1352,14 @@ Slice::ClassDef::createOperation(const string& name,
++q;
while (q != allParams.end())
{
- if (p->second == q->second)
+ //
+ // Complain about duplicate parameters only if they are
+ // non-empty; otherwise, we get a complaint about duplicates
+ // if two or more parameter names are missing in an operation
+ // signature (but the missing parameters have been reported
+ // already).
+ //
+ if (p->second == q->second && p->second != "")
{
string msg = "duplicate parameter `";
msg += p->second;
diff --git a/cpp/src/Slice/Scanner.l b/cpp/src/Slice/Scanner.l
index 93e87e77506..584fcadb877 100644
--- a/cpp/src/Slice/Scanner.l
+++ b/cpp/src/Slice/Scanner.l
@@ -231,6 +231,14 @@ using namespace Slice;
return ICE_OP_KEYWORD;
}
+"out" {
+ return ICE_OUT;
+}
+
+"out"[[:space:]]*"(" {
+ return ICE_OP_KEYWORD;
+}
+
"extends" {
return ICE_EXTENDS;
}