From: Grzegorz J. <ja...@ac...> - 2005-07-09 10:46:16
|
Hello, > Last summer I sent an email about OpenC++ not being able to parse throw > clauses; specifically, whenever I had a throw clause for a method, > OpenC++ would report a parse error. [...] Indeed, we promised to fix this bug once we have resources for it. Unfortunately, we still don't have programmer's time in amounts that would allow to address this bug. [...] > For instance, > the following code would generate a parse error: > > class Person > { > public: > int age; > Person(int a); > int getAge() throw (int); > } > > The throw clause for the method getAge() would cause a parse error. I > sent code to fix this problem (which reimplements the method > Parser::optThrowDecl in the Parser class) for OpenC++ version 2.5.12, > but I got a response (which is the message being forwarded) saying that > my code doesn't really fix the problem. The problem with your code is that it does "too much". As Stefan Seelfeld pointed out, you incorrectly reused function responsible for passing template argumets. I believe your code will accept e.g. int getAge() throw (2) A minor issue is that calling function named 'rTempArgList(q)' for parsing something which is not a template argument list is a serious stilistic abuse --- at least wrap a call in another function whose name aligns with its semantics. Besides fixing the above, test code should be added to OpenC++ to make sure that your fix will not be broken by subsequent maintainers. This is not difficult, but again requires programmer's time. > However, I never had any > problems when I used the code I sent; A I wrote, this is most likely because your code accepts "too much". > I've attached a text file that > contains the code I used to deal with the problem for version 2.5.12 and > 2.8. So I was wondering, will this problem be dealt with for the next > version or will OpenC++ be able to give information about what exception > a method throws if the method has a throw declaration? Thanks. I don't have time to do it myself now. If you would like to invest your time into this project, I would provide support wrt. OpenC++ architecture (where to inject code) and infrastructure (how to run tests, how to add tests etc.) BR Grzegorz > > John Altidor > > ----- Original Message ----- From: "Stefan Seefeld" <se...@sy...> > To: <jal...@st...> > Cc: <ope...@li...> > Sent: Thursday, September 02, 2004 10:55 PM > Subject: Re: [Opencxx-users] Throw Clause Fix > > >> jal...@st... wrote: >> >>> Hello Everyone again, >>> >>> I have fixed the throw clause problem that was in my previous email >>> by changing the body of the method bool Parser::optThrowDecl(Ptree*& >>> throw_decl) in the parser.cc file (for OpenC++ 2.5.12 but each >>> version of OpenC++ has the same implementation for this method). >>> Here is what I changed this method to: >> >> >> [...] >> >> Thanks for the bug report, and thanks for trying to fix it ! >> I don't think your code really solves the problem, though. >> Here is my understanding of the problem: >> >> First note that the ptree fragment that results from parsing the >> declaration >> is never used as of now. (Grzegorz: we should add new ptree nodes for >> this, >> shouldn't we ?) >> optThrowDecl uses 'rName' in a loop, i.e. it assumes the throw specifier >> contains a list of identifiers. That is probably so because in most cases >> what you throw is a class, and as non-builtin types are not looked up >> during >> this stage of the parsing, optThrowDecl simply has to look for >> identifiers. >> Now you put a builtin type there, which the lexer reports as a special >> token, >> which the parser doesn't expect (it expects identifiers !). Boom !! >> >> You have replaced the loop involving 'rName' with 'rTempArgList'. >> That's a method that parses template arguments, which is probably not >> what >> you thought what it does :-) >> >> Anyways I believe as this wasn't really a problem until now we should >> just >> keep a record of this bug (a good case for a unit test to remind us until >> we fix it !) and fix it when we can. That is, I believe, as soon as we >> have a symbol lookup mechanism integrated into the parser, and thus we >> can >> look for a 'list of types'. >> >> Makes sense ? >> >> Thanks for your your help ! >> >> Stefan >> >> >> >> >> ------------------------------------------------------- >> This SF.Net email is sponsored by BEA Weblogic Workshop >> FREE Java Enterprise J2EE developer tools! >> Get your free copy of BEA WebLogic Workshop 8.1 today. >> http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click >> _______________________________________________ >> Opencxx-users mailing list >> Ope...@li... >> https://lists.sourceforge.net/lists/listinfo/opencxx-users >> > /* By John Altidor > * This is my version of Parser::optThrowDecl. > * I used this to build the OpenC++ parser (version 2.8) > * because the OpenC++ parser would interpret throw > * declarations as errors thereby not allowing > * OpenC++ to preprocess C++ files with throw > * declarations. I have not experienced any > * problems with my version. > */ > > bool Parser::optThrowDecl(Ptree*& throw_decl) > { > Token tk; > int t; > Ptree* p = 0; > > if(lex->LookAhead(0) == THROW){ > lex->GetToken(tk); > p = PtreeUtil::Snoc(p, new LeafReserved(tk)); > > if(lex->GetToken(tk) != '(') > return false; > > p = PtreeUtil::Snoc(p, new Leaf(tk)); > > Ptree* q; > t = lex->LookAhead(0); > if(t == '\0') > return false; > else if (rTempArgList(q)) > { > if(lex->GetToken(tk) != ')') > return false; > p = PtreeUtil::Nconc(p, PtreeUtil::List(q, new Leaf(tk))); > } > else > return false; > } > > throw_decl = p; > return true; > } > > /******************************************************************************************/ > > > /* By John Altidor > * This is my version of Parser::optThrowDecl. > * I used this to build the OpenC++ parser (version 2.5.12) > * because the OpenC++ parser would interpret throw > * declarations as errors thereby not allowing > * OpenC++ to preprocess C++ files with throw > * declarations. I have not experienced any > * problems with my version. > */ > > > bool Parser::optThrowDecl(Ptree*& throw_decl) > { > Token tk; > int t; > Ptree* p = nil; > > if(lex->LookAhead(0) == THROW){ > lex->GetToken(tk); > p = Ptree::Snoc(p, new LeafReserved(tk)); > > if(lex->GetToken(tk) != '(') > return FALSE; > > p = Ptree::Snoc(p, new Leaf(tk)); > > Ptree* q; > t = lex->LookAhead(0); > if(t == '\0') > return FALSE; > else if (rTempArgList(q)) > { > if(lex->GetToken(tk) != ')') > return FALSE; > p = Ptree::Nconc(p, Ptree::List(q, new Leaf(tk))); > } > else > return FALSE; > } > > throw_decl = p; > return TRUE; > } |