diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/Grammer.y | 134 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.cpp | 267 | ||||
-rw-r--r-- | cpp/src/Slice/Parser.h | 4 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Main.cpp | 24 |
4 files changed, 325 insertions, 104 deletions
diff --git a/cpp/src/Slice/Grammer.y b/cpp/src/Slice/Grammer.y index 43a38281e1d..32cc26d8504 100644 --- a/cpp/src/Slice/Grammer.y +++ b/cpp/src/Slice/Grammer.y @@ -21,6 +21,12 @@ yyerror(const char* s) unit -> error(s); } +void +yyerror(const string& s) +{ + unit -> error(s.c_str()); +} + %} %token ICE_SCOPE_DELIMITOR @@ -170,6 +176,8 @@ module_def StringTok_ptr ident = StringTok_ptr::dynamicCast($2); Container_ptr cont = unit -> currentContainer(); Module_ptr module = cont -> createModule(ident -> v); + if(!module) + YYERROR; // Can't continue, jump to next yyerrok unit -> pushContainer(module); } '{' definitions '}' @@ -225,6 +233,8 @@ class_def local -> v, false, bases -> v); + if(!cl) + YYERROR; // Can't continue, jump to next yyerrok unit -> pushContainer(cl); } '{' class_exports '}' @@ -241,30 +251,31 @@ class_extends StringTok_ptr scoped = StringTok_ptr::dynamicCast($2); Container_ptr cont = unit -> currentContainer(); list<Type_ptr> types = cont -> lookupType(scoped -> v); - assert(!types.empty()); // TODO - ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); - if(!cl) - { - string msg = "`"; - msg += scoped -> v; - msg += "' is not a class"; - yyerror(msg.c_str()); - $$ = 0; - } - else + $$ = 0; + if(!types.empty()) { - ClassDef_ptr def = cl -> definition(); - if(!def) + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); + if(!cl) { string msg = "`"; msg += scoped -> v; - msg += "' has been declared but not defined"; - yyerror(msg.c_str()); - $$ = 0; + msg += "' is not a class"; + yyerror(msg); } else { - $$ = def; + ClassDef_ptr def = cl -> definition(); + if(!def) + { + string msg = "`"; + msg += scoped -> v; + msg += "' has been declared but not defined"; + yyerror(msg); + } + else + { + $$ = def; + } } } } @@ -314,6 +325,8 @@ interface_def local -> v, true, bases -> v); + if(!cl) + YYERROR; // Can't continue, jump to next yyerrok unit -> pushContainer(cl); } '{' interface_exports '}' @@ -332,28 +345,30 @@ interface_list StringTok_ptr scoped = StringTok_ptr::dynamicCast($1); Container_ptr cont = unit -> currentContainer(); list<Type_ptr> types = cont -> lookupType(scoped -> v); - assert(!types.empty()); // TODO - ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); - if(!cl || !cl -> isInterface()) - { - string msg = "`"; - msg += scoped -> v; - msg += "' is not an interface"; - yyerror(msg.c_str()); - } - else + if(!types.empty()) { - ClassDef_ptr def = cl -> definition(); - if(!def) + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); + if(!cl || !cl -> isInterface()) { string msg = "`"; msg += scoped -> v; - msg += "' has been declared but not defined"; - yyerror(msg.c_str()); + msg += "' is not an interface"; + yyerror(msg); } else { - intfs -> v.push_front(def); + ClassDef_ptr def = cl -> definition(); + if(!def) + { + string msg = "`"; + msg += scoped -> v; + msg += "' has been declared but not defined"; + yyerror(msg); + } + else + { + intfs -> v.push_front(def); + } } } } @@ -364,28 +379,30 @@ interface_list StringTok_ptr scoped = StringTok_ptr::dynamicCast($1); Container_ptr cont = unit -> currentContainer(); list<Type_ptr> types = cont -> lookupType(scoped -> v); - assert(!types.empty()); // TODO - ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); - if(!cl || !cl -> isInterface()) + if(!types.empty()) { - string msg = "`"; - msg += scoped -> v; - msg += "' is not an interface"; - yyerror(msg.c_str()); - } - else - { - ClassDef_ptr def = cl -> definition(); - if(!def) + ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(types.front()); + if(!cl || !cl -> isInterface()) { string msg = "`"; msg += scoped -> v; - msg += "' has been declared but not defined"; - yyerror(msg.c_str()); + msg += "' is not an interface"; + yyerror(msg); } else { - intfs -> v.push_front(def); + ClassDef_ptr def = cl -> definition(); + if(!def) + { + string msg = "`"; + msg += scoped -> v; + msg += "' has been declared but not defined"; + yyerror(msg); + } + else + { + intfs -> v.push_front(def); + } } } } @@ -554,7 +571,14 @@ type ++p) { ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p); - assert(cl); // TODO: Only classes can be passed as proxy + if(!cl) + { + string msg = "`"; + msg += scoped -> v; + msg += "' must be class or interface"; + yyerror(msg); + YYERROR; // Can't continue, jump to next yyerrok + } *p = new Proxy(cl); } $$ = types.front(); @@ -634,20 +658,22 @@ identifier_list : ICE_IDENTIFIER ',' identifier_list { StringTok_ptr ident = StringTok_ptr::dynamicCast($1); - Container_ptr cont = unit -> currentContainer(); - Enumerator_ptr en = cont -> createEnumerator(ident -> v); StringListTok_ptr ens = StringListTok_ptr::dynamicCast($3); - ens -> v.push_front(ident -> v); $$ = ens; + Container_ptr cont = unit -> currentContainer(); + Enumerator_ptr en = cont -> createEnumerator(ident -> v); + if(en) + ens -> v.push_front(ident -> v); } | ICE_IDENTIFIER { StringTok_ptr ident = StringTok_ptr::dynamicCast($1); - Container_ptr cont = unit -> currentContainer(); - Enumerator_ptr en = cont -> createEnumerator(ident -> v); StringListTok_ptr ens = new StringListTok; - ens -> v.push_front(ident -> v); $$ = ens; + Container_ptr cont = unit -> currentContainer(); + Enumerator_ptr en = cont -> createEnumerator(ident -> v); + if(en) + ens -> v.push_front(ident -> v); } ; diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp index 04f7b3add7b..7d90baaf121 100644 --- a/cpp/src/Slice/Parser.cpp +++ b/cpp/src/Slice/Parser.cpp @@ -204,7 +204,11 @@ Slice::Container::createModule(const string& name) if(module) continue; // Reopening modules is permissible - assert(false); // TODO: Already exists and not a module + string msg = "redefinition of `"; + msg += name; + msg += "' as module"; + yyerror(msg); + return 0; } Module_ptr q = new Module(this, name); @@ -223,16 +227,42 @@ Slice::Container::createClassDef(const string& name, bool local, bool intf, { ClassDecl_ptr cl = ClassDecl_ptr::dynamicCast(*p); if(cl) - continue; // TODO: Check whether local and interface matches + { + if(checkInterfaceAndLocal(name, false, + intf, cl -> isInterface(), + local, cl -> isLocal())) + continue; + + return 0; + } - if(unit_ -> ignRedefs()) + ClassDef_ptr def = ClassDef_ptr::dynamicCast(*p); + if(def) { - ClassDef_ptr def = ClassDef_ptr::dynamicCast(*p); - if(def) + if(unit_ -> ignRedefs()) return def; - } - assert(false); // TODO: Already exists and not a class declaration + string msg = "redefinition of "; + if(intf) + msg += "interface"; + else + msg += "class"; + msg += " `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; + } + + string msg = "redefinition of `"; + msg += name; + msg += "' as "; + if(intf) + msg += "interface"; + else + msg += "class"; + yyerror(msg); + return 0; } ClassDef_ptr def = new ClassDef(this, name, local, intf, bases); @@ -269,17 +299,38 @@ Slice::Container::createClassDecl(const string& name, bool local, bool intf) ClassDef_ptr clDef = ClassDef_ptr::dynamicCast(*p); if(clDef) { - assert(!def); - def = clDef; - continue; // TODO: Check whether local and interface matches + if(checkInterfaceAndLocal(name, true, + intf, clDef -> isInterface(), + local, clDef -> isLocal())) + { + assert(!def); + def = clDef; + continue; + } + + return 0; } ClassDecl_ptr clDecl = ClassDecl_ptr::dynamicCast(*p); if(clDecl) - continue; // TODO: Check whether local and interface matches - - // TODO: Already defined as something other than a class - assert(false); + { + if(checkInterfaceAndLocal(name, false, + intf, clDecl -> isInterface(), + local, clDecl -> isLocal())) + continue; + + return 0; + } + + string msg = "declaration of already defined `"; + msg += name; + msg += "' as "; + if(intf) + msg += "interface"; + else + msg += "class"; + yyerror(msg); + return 0; } // @@ -316,14 +367,24 @@ Slice::Container::createVector(const string& name, const Type_ptr& type) ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + Vector_ptr p = Vector_ptr::dynamicCast(matches.front()); + if(p) { - Vector_ptr p = Vector_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; + + string msg = "redefinition of vector `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; } - assert(false); // TODO: Already exits + string msg = "redefinition of `"; + msg += name; + msg += "' as vector"; + yyerror(msg); + return 0; } Vector_ptr p = new Vector(this, name, type); @@ -337,14 +398,24 @@ Slice::Container::createEnum(const string& name, const StringList& enumerators) ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + Enum_ptr p = Enum_ptr::dynamicCast(matches.front()); + if(p) { - Enum_ptr p = Enum_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; + + string msg = "redefinition of enum `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; } - assert(false); // TODO: Already exits + string msg = "redefinition of `"; + msg += name; + msg += "' as enum"; + yyerror(msg); + return 0; } Enum_ptr p = new Enum(this, name, enumerators); @@ -358,14 +429,24 @@ Slice::Container::createEnumerator(const std::string& name) ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + Enumerator_ptr p = Enumerator_ptr::dynamicCast(matches.front()); + if(p) { - Enumerator_ptr p = Enumerator_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; + + string msg = "redefinition of enumerator `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; } - assert(false); // TODO: Already exits + string msg = "redefinition of `"; + msg += name; + msg += "' as enumerator"; + yyerror(msg); + return 0; } Enumerator_ptr p = new Enumerator(this, name); @@ -379,14 +460,24 @@ Slice::Container::createNative(const string& name) ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + Native_ptr p = Native_ptr::dynamicCast(matches.front()); + if(p) { - Native_ptr p = Native_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; + + string msg = "redefinition of native `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; } - assert(false); // TODO: Already exits + string msg = "redefinition of `"; + msg += name; + msg += "' as native"; + yyerror(msg); + return 0; } Native_ptr p = new Native(this, name); @@ -407,7 +498,14 @@ Slice::Container::lookupType(const string& scoped) if(matches.empty()) { Contained_ptr contained = Contained_ptr::dynamicCast(this); - assert(contained); // TODO: Not found error + if(!contained) + { + string msg = "`"; + msg += scoped; + msg += "' is not defined"; + yyerror(msg); + return TypeList(); + } return contained -> container() -> lookupType(scoped); } else @@ -422,7 +520,14 @@ Slice::Container::lookupType(const string& scoped) continue; // Ignore class definitions Type_ptr type = Type_ptr::dynamicCast(*p); - assert(type); // TODO: Not a type error + if(!type) + { + string msg = "`"; + msg += scoped; + msg += "' is not a type"; + yyerror(msg); + return TypeList(); + } results.push_back(type); } return results; @@ -598,6 +703,64 @@ Slice::Container::Container(const Unit_ptr& unit) includeLevel_ = 0; } +bool +Slice::Container::checkInterfaceAndLocal(const string& name, bool defined, + bool intf, bool intfOther, + bool local, bool localOther) +{ + string definedOrDeclared; + if(defined) + definedOrDeclared = "defined"; + else + definedOrDeclared = "declared"; + + if(!intf && intfOther) + { + string msg = "class `"; + msg += name; + msg += "' was "; + msg += definedOrDeclared; + msg += " as interface"; + yyerror(msg); + return false; + } + + if(intf && !intfOther) + { + string msg = "interface `"; + msg += name; + msg += "' was "; + msg += definedOrDeclared; + msg += " as class"; + yyerror(msg); + return false; + } + + if(!local && localOther) + { + string msg = "non-local `"; + msg += name; + msg += "' was "; + msg += definedOrDeclared; + msg += " local"; + yyerror(msg); + return false; + } + + if(local && !localOther) + { + string msg = "local `"; + msg += name; + msg += "' was "; + msg += definedOrDeclared; + msg += " non-local"; + yyerror(msg); + return false; + } + + return true; +} + // ---------------------------------------------------------------------- // Module // ---------------------------------------------------------------------- @@ -707,14 +870,24 @@ Slice::ClassDef::createOperation(const string& name, ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + Operation_ptr p = Operation_ptr::dynamicCast(matches.front()); + if(p) { - Operation_ptr p = Operation_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; + + string msg = "redefinition of operation `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; } - assert(false); // TODO: Already exits + string msg = "redefinition of `"; + msg += name; + msg += "' as operation"; + yyerror(msg); + return 0; } Operation_ptr p = new Operation(this, name, returnType, @@ -731,14 +904,24 @@ Slice::ClassDef::createDataMember(const string& name, const Type_ptr& type) ContainedList matches = unit_ -> findContents(thisScope() + name); if(!matches.empty()) { - if(unit_ -> ignRedefs()) + DataMember_ptr p = DataMember_ptr::dynamicCast(matches.front()); + if(p) { - DataMember_ptr p = DataMember_ptr::dynamicCast(matches.front()); - if(p) + if(unit_ -> ignRedefs()) return p; - } - assert(false); // TODO: Already exits + string msg = "redefinition of data member `"; + msg += name; + msg += "'"; + yyerror(msg); + return 0; + } + + string msg = "redefinition of `"; + msg += name; + msg += "' as data member"; + yyerror(msg); + return 0; } DataMember_ptr p = new DataMember(this, name, type); @@ -1317,6 +1500,8 @@ Slice::Unit::parse(FILE* file, bool debug) extern FILE* yyin; yyin = file; int status = yyparse(); + if(yynerrs) + status = EXIT_FAILURE; assert(containerStack_.size() == 1); popContainer(); diff --git a/cpp/src/Slice/Parser.h b/cpp/src/Slice/Parser.h index 6dbd1826c0e..fe4bc2df77d 100644 --- a/cpp/src/Slice/Parser.h +++ b/cpp/src/Slice/Parser.h @@ -22,6 +22,7 @@ extern int yynerrs; int yyparse(); int yylex(); void yyerror(const char* s); +void yyerror(const std::string& s); namespace Slice { @@ -297,6 +298,9 @@ protected: Container(const Unit_ptr&); + bool checkInterfaceAndLocal(const std::string&, bool, + bool, bool, bool, bool); + int includeLevel_; ContainedList contents_; }; diff --git a/cpp/src/slice2cpp/Main.cpp b/cpp/src/slice2cpp/Main.cpp index 98c21ca0058..5ca04edff48 100644 --- a/cpp/src/slice2cpp/Main.cpp +++ b/cpp/src/slice2cpp/Main.cpp @@ -128,6 +128,8 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } + int status = EXIT_SUCCESS; + for(idx = 1 ; idx < argc ; ++idx) { string base(argv[idx]); @@ -169,7 +171,7 @@ main(int argc, char* argv[]) } Unit_ptr unit = Unit::createUnit(false, false); - int status = unit -> parse(cppHandle, debug); + int parseStatus = unit -> parse(cppHandle, debug); #ifdef WIN32 _pclose(cppHandle); @@ -177,16 +179,20 @@ main(int argc, char* argv[]) pclose(cppHandle); #endif - if(status == EXIT_FAILURE) - return status; - - Gen gen(argv[0], base, include, includePaths, dllExport); - if(!gen) - return EXIT_FAILURE; - gen.generate(unit); + if(parseStatus == EXIT_FAILURE) + { + status = EXIT_FAILURE; + } + else + { + Gen gen(argv[0], base, include, includePaths, dllExport); + if(!gen) + status = EXIT_FAILURE; + gen.generate(unit); + } unit -> destroy(); } - return EXIT_SUCCESS; + return status; } |