From: Grzegorz J. <ja...@he...> - 2003-03-17 09:23:56
|
On Fri, 14 Mar 2003, Stefan Reuther wrote: > Hello, > > On Thu, Mar 13, 2003 at 01:52:52PM +0800, Grzegorz Jakacki wrote: > > This is very important, as this allows somebody who is not a guru to come > > and commit some fixes without fear that he/she breaks some distant parts > > of the package. Our testsuite is pathetically small at the moment, but > > it already helps and I believe that it can grow. > > I think, there are two problems, at least with the parser. The > interface consists of two parts, namely the Ptree descendants > and their contents. > > 1) Every Ptree descendant has a method "Translate" which calls > a method of Walker. Adding a new Ptree class means adding a > method to Walker. This is the first sign of too little isolation between visitor (Walker) and visited class hierarchy (Ptree and derived classes) --- you cannot extend Ptree hierarchy without modifying Walker code. > User code must override that method, or > they'll (accidentially, maybe) run into the default behaviour > which just recurses into the subtrees. I am not sure if I understand you here. When the user adds the method of Walke, he/she is free to define the default behavious as he/she wants, right? Or maybe you mean, that *some* default behavious has to be defined, since the member function cannot be just left abstract, because otherwise user would make Walker class abstract? > This problem can be > solved with an abstract base class, so people who want to be > paranoid can derive from that. Right, but then they have to define traversals in all 'Translate()' overloads by themselves. > Their code will automatically > fail to compile when we add a new node type, which is a Good > Thing(tm), IMHO. It depends. When I am adding new node to store '__attribute__' GNU extension, I do not want old code to fail. I would prefere a design, in which I can do it so that new code can see '__attribute__' node, while old code does not see it. > > So far, everything nice. > > 2) The bigger problem is with the content of the nodes. For > example, the new wide-char constants turn into Leafs. Old > programs might assume that all Leafs are either numeric, char > or string literals, and break now. Or, my "if(decl)" patch[1] > would add the new property that the third child of "if" can > be a declaration instead of an expression. I don't see a good > solution for that problem. Okay, one could go away from the > Lispy data structure towards a more "explicit" syntax, i.e. > class PtreeIfStatement { > Ptree *if_keyword, *left_paren, *right_paren; > PtreeExpressionOrDeclaration *condition; > PtreeStatement *controlled_statement; > }; Precisely. In fact OpenC++ does not use the "Lispy data structure" (I really like this term!). The abstract datatypes that you envision are already present --- look at the names of Metaclass methods --- they are candidates for the new syntax hierarchy. Such hierarchy would be much safer to play with: instead of "ifthenelse->Car()->Car()->Cdr()", which potentially can coredump at each arrow, one would conveniently write "ifthenelse->GetThen()". Also if sometime in the future the representation of "PtreeIfStatement" node changes, then client using "ifthenelse->GetThen()" would feel good, while the client using "ifthenelse->Car()->Car()->Cdr()" would have to fix his/her Car()s and Cdr()s. > but that would need an enormous amount of work and break > everything. If you just throw away Ptree's and introduce new hierarchy, then yes. But there is much better way: one can wrap raw tree implementation (like Ptree) into better-structured one using wrapper types (which are implementation of Proxy pattern). The technique I am trying to come up with for it is mainly based on so-called traits (classes similar to e.g. numeric_limits<> from Standard Library) and type-safe visitation (similar to technique used in boost::visitor). Introduction of wrappers does not break any existing code, but makes the new code much better isolated from the actual tree representation, so changes in the tree representation (even adding new nodes) does not break the new code. > Plus, OpenC++ started as a meta-object protocol > and not as a parser library, so I'm perfectly happy when it > fulfills its primary purpose best :-) As C++ changes the meta-object protocol has to change also. Apart of that, OpenC++ is the most reasonable non-GPL'd C++ frontend approximation I know of. > [1] Since the CVS code currently can't be built, I'll wait with > checking it in. Ok. > > But now comes the problem: when we just extend Frontend itself, without > > proper support in Translator (e.g. your patches will make 'if ({...}) ' > > parse, but Translator will choke on it), we do not have way to add tests > > that make sure the new Frontend functionality works. > > My 1) is a partial solution. But this requires adding *some* support of new nodes to the translator anyway, right? > 2) can be solved by very defensive > programming. Which is a maintenance nightmare and I would like to avoid it. > My code checks every Ptree node it encounters > whether it fits into its imagination. For example, my "if" > handling code starts with (the equivalent of) > assert(p->First()->Eq("if")); > assert(p->Second()->Eq('(')); > assert(p->Nth(3)->Eq(')')); > so if someone now adds an "unless" statement which also > generates a PtreeIfStatement ("it's almost the same"), my code > will see that it can't handle it. I think we can't get much > better. Not with the design in place. > > BTW: Over a year ago there was a resolution on this forum to factor out the > > Driver subsystem and make it a shell script (for easier maintenance > > and to make underlying compiler/preproc/linker settable with Autoconf). > > Personally, I don't care whether the driver is in C, Perl, Shell > or Intercal. I do, because I am responding to bug reports :-) (Seriously: shell is the only solution that does not have to duplicate libtool functionality, e.g. to know how to install shared library on the given platform). > What about generating a ".h" file and including that in the > driver? In another project of mine, I have this in "configure.in": > ----8<---- > define(CREATE1, [AC_OUTPUT_COMMANDS([echo "creating $1..." > cat >conftest.tmp <<_EOF > $2 > _EOF > if cmp -s $1 conftest.tmp; then > echo $1 is unchanged > rm -f conftest.tmp > else > rm -f $1 > mv conftest.tmp $1 > fi])])dnl > > CREATE1(arch/platform.h, [#ifndef PCC_V2_ARCH_PLATFORM_H > #define PCC_V2_ARCH_PLATFORM_H > #define PCC2_SRCDIR "`cd "$srcdir" && pwd`" > #define PCC2_DATADIR "$pdatadir" > #include "arch/unix/platform.h" > #endif > ]) > ----8<---- > This creates a file ("arch/platform.h") which contains the > specified code, with shell variables expanded (Disclaimer: I'm > not an Autoconf expert, maybe what I did can be done much > easier). AC_DEFINE is the solution you are looking for. What you suggest is reasonable for e.g. setting compiler or setting the proper shared lib extension (.so, .dynlib etc.), but apart of those there is *functionality* which is necessary in driver. How will you pass the knowledge about the correct way of installing shared library? On some platforms you just do 'cp'. On some you also have to set up dynamic linker somehow. On yet other platforms you have to run special program on the new shared library to activate it. On some you have to make appropriate symlinks. I do not want to maintain code that takes care of all this, especially that this code has already been written and is called libtool. > In addition, setting these variables with options to the driver > is a nice thing to have. Shouldn't be too hard. I'm currently > fiddling around with symlinks in $HOME/bin. I do not quite understand. What do you use symlinks for? > Not too great :-P > On the other hand, there's always the option to just translate > the source (-E) and compile manually. And that was basically what I would like occ executable to do. No more, no less. Best regards Grzegorz PS: I promised to prepare a write-up on the solution I have in mind, but although I was trying hard thorughout the weekend, I still do not have it in satisfactory form. Hopefully I will be able to mail it tomorrow. G. ################################################################## # Grzegorz Jakacki Huada Electronic Design # # Senior Engineer, CAD Dept. 1 Gaojiayuan, Chaoyang # # tel. +86-10-64365577 x2074 Beijing 100015, China # # Copyright (C) 2002 Grzegorz Jakacki, HED. All Rights Reserved. # ################################################################## |