Il y a deux choses *interdites* qui ont l'air d'être faites très
souvent dans Tfers :
- Utiliser @ pour cacher les commandes dans un Makefile.
C'est une erreur grave !
- Ne pas utiliser argv[0] dans les messages d'erreur.
Ne surtout *jamais* coder un nom en dur, du genre SdfChecker,
dans les messages d'erreur, les logs, etc., mais bel et bien
argv[0]. Sinon, ceux qui debuggent vous maudissent !
Merci d'en tenir compte et de réparer tous les endroits malades de Tfers.
Je trouve que c'est une erreur d'avoir autant de paquets dans notre
arbre. C'est une contrainte, quelque chose qui nuit à la
productivité. Si un jour il faut rendre un paquet autonome, ce serait
facile de l'arnacher, mais entre temps, je propose la suppression de
tous les configure.ac intermédiaires. Seul le bundle compte.
Quand je fais un make dans c-condition/src/syn :
SdfChecker:warning: unused sort definitions in /tmp/StrategoXT5Sm1zB, line 662, col 8: ExpressionList
SdfChecker:warning: unused sort definitions in /tmp/StrategoXT5Sm1zB, line 268, col 8: TypeSpecifierSeq
>>> "Valentin" == Valentin David <valentin.david(a)gmail.com> writes:
> On 9/20/05, Akim Demaille <akim(a)lrde.epita.fr> wrote:
>> Je trouve que c'est une erreur d'avoir autant de paquets dans notre
>> arbre. C'est une contrainte, quelque chose qui nuit à la
>> productivité. Si un jour il faut rendre un paquet autonome, ce serait
>> facile de l'arnacher, mais entre temps, je propose la suppression de
>> tous les configure.ac intermédiaires. Seul le bundle compte.
> Why changing something that works? It was long to set, but now it does
> not need so much maintaining. It is good to have a build farm that
> check each packages, reading the logs is easier.
I'm sorry, but it is not my view that it is working: with Alexandre we
lost almost 1 man-day because the C grammar he thought he was using
(the one in the src tree) was not the one that was used (the last one
to be installed). In addition it is common knowledge that the
Autotools are *very* costly to run: any improvement of the working
cycle in the Tfers project is an healthy move.
I might agree for the removal of *some* indirections instead of all of
them, but as is as of today, it is ridiculous --- you can't justify so
many packages.
I propose 3 sub packages:
- StrategoXTensions
boxedsdf
esdf
sdf-astgen
sdf-attribute
sdf-detgen
sdf-option
str-lazy
- C Grammars
c-condition
c-grammar
- C++ Grammars
cxx-basic
cxx-grammar
specs-grammar
I'm reading the module prepost, and there are a few issues I would
like to raise.
Disclaimer: I have never programmed in Stratego, the code is most
certainly wrong.
1. The complete file
====================
For reference.
imports
liblib
ContractC
strategies
SearchFunDecl = alltd({
?|InitDeclarator[ ~Declarator: <id>~ ]| ; debug
; oncetd(?|DirectDeclarator[ ~ID: fun_name~ ]|)
; oncetd(
?|DirectDeclarator[
DirectDeclarator(ParameterTypeList)
PreCondition-opt
PostCondition-opt ]|
; !PreCondition-opt
; if ?|PreCondition?[ ]| then
!|Statement[ ; ]| => pre
else
?|PreCondition?[
precondition { ~Assertion+: pre~ } ]|
end
; !PostCondition-opt
; if ?|PostCondition?[ ]| then
!|Statement[ ; ]| => post
; !|ReturnValueDeclaration?[ ]| => ret
else
?|PostCondition?[
postcondition ~ReturnValueDeclaration?: ret~
{ ~Assertion+: post~ } ]|
end
; !|DirectDeclarator[
DirectDeclarator(ParameterTypeList) ]|)
; rules (PrePost : fun_name -> (pre, ret, post))
})
SearchFunDef = alltd({
?|ExternalDeclaration[ ~FunctionDefinition: <id> ~ ]|
; oncetd(?|DirectDeclarator[ ~ID: fun_name ~ ]|
; where(<PrePost> fun_name => (pre, ret, post))
; oncetd(?|BlockItemList[ BlockItem-iter ]|
; !|BlockItemList[ ~BlockItem+:
<concat> [
[|BlockItem[ ~CompoundStatement: pre ~ ]|,
|BlockItem[ ~CompoundStatement: post ~ ]|],
BlockItem-iter
]~]|
))
})
prepost = io-wrap(SearchFunDecl ; SearchFunDef)
2. The strategies
=================
First of all, why the heck should the alltd be in the rules? And BTW,
why the rules are strategies here? As a first improvement, I propose
to move the alltd down to the prepost strategy.
prepost = io-wrap(alltd (FunDecl) ; alltd (FunDef))
Then you see that there are two alltd. Although this allows to have
declarations after the implementation (which is indeed a feature) it
goes against the spirit of C. Therefore it should read
prepost = io-wrap(alltd (FunDecl ; FunDef))
Also, *save the space*! What is this fashion of starting to implement
immediately after `='?
FunDecl =
{
?|InitDeclarator[ ~Declarator: <id>~ ]| ; debug
; oncetd(?|DirectDeclarator[ ~ID: fun_name~ ]|)
; oncetd(
?|DirectDeclarator[
DirectDeclarator(ParameterTypeList)
PreCondition-opt
PostCondition-opt ]|
; !PreCondition-opt
; if ?|PreCondition?[ ]| then
!|Statement[ ; ]| => pre
else
?|PreCondition?[
precondition { ~Assertion+: pre~ } ]|
end
; !PostCondition-opt
; if ?|PostCondition?[ ]| then
!|Statement[ ; ]| => post
; !|ReturnValueDeclaration?[ ]| => ret
else
?|PostCondition?[
postcondition ~ReturnValueDeclaration?: ret~
{ ~Assertion+: post~ } ]|
end
; !|DirectDeclarator[
DirectDeclarator(ParameterTypeList) ]|)
; rules (PrePost : fun_name -> (pre, ret, post))
}
FunDef =
{
?|ExternalDeclaration[ ~FunctionDefinition: <id> ~ ]|
; oncetd(?|DirectDeclarator[ ~ID: fun_name ~ ]|
; where(<PrePost> fun_name => (pre, ret, post))
; oncetd(?|BlockItemList[ BlockItem-iter ]|
; !|BlockItemList[ ~BlockItem+:
<concat> [
[|BlockItem[ ~CompoundStatement: pre ~ ]|,
|BlockItem[ ~CompoundStatement: post ~ ]|],
BlockItem-iter
]~]|
))
}
3. The rules
============
The rules exist, and that's because they make sense. Why just making
strategies? I know, they are equivalent, but so are for and while
loops, and you do use both.
What is the InitDeclarator that we start by matching? Apparently it
is only for debugging, but that's cluttering the code. What are all
these oncetd doing here? This is *so wrong*: the code is trying to
match various piece instead of just matching what it's looking for.
IMNSHO it should look like:
FunDecl =
? |Declarator[fn (arg*) pre post]|
; rules (PrePost : fn -> (cs1*, i, cs2*))
where <?|[precondition { cs1* }]|> (pre);
<?|[postcondition (i) { cs2* }]|> (post)
Is there a nicer way to match pre*, ret and post*? And we'll see for
the function with either a pre- xor a postcondition later...
The other rule/strategy is also quite not understandable!
What is to be done is to create a dynamic rule *that performs the
replacement*!!! Not some pseudo table, which completely defeats the
whole point of dynamic rules.
We want to write something like:
where
When you put the two together, you have:
FunDecl =
? |Declarator[fn (arg*) pre post]|
; rules (InstallContract :
|FunctionDefinition[fn (arg*) { stm* }] => !|[fn (arg*) { stm'* }]
where <?|[precondition { cs1* }]|> (pre);
<?|[postcondition (i) { cs2* }]|> (post);
<install-contract (cs1*, i, cs2*)> (stm) => stm'*)
And for an experimental start, I propose
install-contract (|cs1*, i, cs2*) =
!|[ { cs1* } ~id { cs2*} ]|
We will see the complications later.
I would like to have detailed answers, and particularly from Jesus.
I'm quite sure my code is wrong, but it is probably close to correct,
my Stratego is far from fluent.
Hi,
I did not understand some behaviors of Gcc. Gcc accepts this:
-->8--
class A {};
class B {};
A B;
-->8--
I found nothing in the standard that says it is not valid. Ok.
According to the standard this one is valid, and Gcc accepts it:
-->8--
typedef int T;
typedef int T;
-->8--
It does not accept this one:
-->8--
typedef int T;
T T;
-->8--
That is ok, T is a typedef-name.
But on this one, it fails:
-->8--
class A {};
typedef A T;
T T;
-->8--
But normally, T is class-name.
And the same on this one:
-->8--
typedef class {} A;
A A;
-->8--
But here, A is not only a class-name, it is *THE* real name of the class.
I do not understand why Gcc does not accept these two last examples. I
did not find it in the standard. If someone find it somewhere...
--
Valentin David
valentin.david(a)gmail.com