<<

Syntactic Sugar Support for Advanced ++ Constructs

Thomas Largillier

Technical Report no0515, July 2005 revision 933

The LRDE is developing two libraries, Olena [4] and Vaucanson [7] which both have high requirements concerning code efficiency and speed. They have to use many paradigms based on efficiency. Writing efficient code becomes quickly equivalent to writing cryptic code. Then the written is almost write-only and obviously this is not a good point concerning code writing and the maintainability of an application. Here we provide a method to help the developers by adding sugar to C++. This method is based on island grammars and developted with the Stratego/XT [10] tools. Le LRDE développe deux bibliotheques, Olena et Vaucanson, qui sont tres concernees par les aspects de genericite de de performance. Elles utilisent de nombreux paradigmes amenant ces deux aspects. Ecrire du code efficace et generique revient rapidement a ecrire du code assez cryptique. Le code ecrit est qua- siment illisible ce qui evidemment freine son ecriture et diminue sa maintenabilite. Ici est presentee une methode pour aider les developeurs en ajoutant du sucre au C++. La methode est basee sur l’ecriture ’une grammaire a iles et developpee avec l’environnement Stratego/XT. Keywords Island grammars, program transformation, syntactic sugar 2

Laboratoire de Recherche et Développement de l’Epita 14-16, rue Voltaire – F-94276 Le Kremlin-Bicêtre cedex – France Tél. +33 1 53 14 59 47 – Fax. +33 1 53 14 59 22 [email protected] – Transformers 3

Copying this document

Copyright c 2005 LRDE. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with the Invariant Sections being just “Copying this document”, no Front- Cover Texts, and no Back-Cover Texts. A copy of the license is provided in the file COPYING.DOC. Contents

1 Cxx syntax limitations 6 1.1 Overview of the syntax ...... 6 1.2 Limitations ...... 6 1.3 Example ...... 7

2 Island grammars 8 2.1 Presentation ...... 8 2.1.1 Definition ...... 8 2.1.2 Concepts ...... 9 2.2 Interests ...... 9 2.2.1 General ...... 9 2.2.2 Desugaring ...... 9 2.3 Use ...... 10 2.3.1 Grammar extensions ...... 10 2.4 Drawbacks ...... 10

3 Cxx_desugar 11 3.1 Tools ...... 11 3.1.1 eSDF ...... 11 3.1.2 Stratego ...... 12 3.1.3 SGLR ...... 13 3.2 The pipeline ...... 14 3.3 Sugars provided ...... 15 3.3.1 The meta tag ...... 15 3.3.2 Virtual typedefs ...... 15 3.4 Future work ...... 18 3.4.1 More sugar ...... 18 3.4.2 More checking ...... 19

4 Bibliography 21 5 CONTENTS

Introduction

The Transformers project [8] was born in the LRDE to help the developers working on Olena [4] and Vaucanson [7]. Indeed both of these projects, developed in C++ language, are using several notions to improve code efficiency and speed. Most of these notions were even created in the LRDE for the need of being efficient and remaining as generic as possible.

The major drawback of these paradigm is, since they were invented very recently, there is no language that supports them in a native way. This obliges the developers to find some syntactic constructs to express these notions in C++. Actually finding C++ constructs corresponding with the ideas is not the most difficult part since the developers are very familiar with this language. The problems are the constructs themselves.

Actually they are often heavy, unnatural and complex. This increases the developing phase of the libraries since the programmer has more code to write. Moreover new programmers joining the LRDE each year loose a relevant time understanding these notions and learning how to write efficient code using these paradigms.

Here we provide some syntactic sugar to C++ in order to simplify the writing of efficient and generic code. This sugar was suggested by Thierry Géraud, Olena team leader. Since they are using many static paradigms to increase the speed of their libraries, the source code becomes quickly a huge amount of "template" methods and values. This is why they need some constructs syntactically and semantically clearer.

The sugar and the desugaring process are based on an island grammar. This work should obviously be done in a short amount of time. The time saved writing light constructs should not be lost in the desugaring process. We also have to take care of our own efficiency in ad- dition of the effectiveness of the produced code. Since we are only realising source to source tranformations and not compiling the source given to the program. Chapter 1

Cxx syntax limitations

1.1 Overview of the syntax

The C++ is a language where you can express almost everything thanks to the mixing of two paradigms: the Object Oriented Paradigm (OOP) and the Generic Programming Paradigm (GP). Both of these paradigms are well supported in the language. Thanks to the inheritance given by OOP and the template keyword provided for GP, the last one providing generic code and meta-computation. Olena and Vaucanson are able to express almost everything they want in this language since it is less restrictive than other popular languages (Java, Eiffel, . . . ) and also for its efficient compile- time computation system provided by the template parameters for classes and functions.

Even if we are able to express many paradigms in C++, the problem here is that there are only few mechanisms to express these notions in this language, basically only hierarchies and the template keyword. Then developers need to be very clever and asticious to find the good constructs according to their ideas, trying to keep a link between the syntax and the semantics. This could be hard some time but does not represent the major problem. Here the most important is that these constructs are mostly heavy, unnatural and complex. The reason is the small amount of syntatic constructs offered to the developer. Then we provide more syntactic constructs in order to help developers to clarify their code and add some semantic. The idea is to bring closer the semantic and the syntax.

1.2 Limitations

If these things are considered as limitations, even if programmers can express every notion in C++, it is because they really slow down the developing process of the application and reduce the maintainability of the project. These limitations are really induced by the syntax and not the paradigms because if we imag- ine a clearer syntax for these notions that could help the developer in writing his code, this will reduces the writing time and increases the maintainability of the project. These limitations should not be ignored, indeed, when new students are joining the LRDE each year, they lose a relevant amount of time to learn the paradigms and how to write code 7 Cxx syntax limitations

using them. With a clearer syntax, the time spent to learn how to write efficient code could be reduced.

1.3 Example

This is an example of code that has become cryptic.

1 # ifndef OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH 2 # define OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH 3 4 # include 5 # include 6 7 8 namespace oln { 9 10 11 / / fwd d e c l 12 namespace a b s t a c t { 13 template s t r u c t image_by_delegation ; 14 } 15 16 // super type 17 18 template 19 s t r u c t set_super_type < abstract::image_by_delegation< I, E> > 20 { typedef abstract ::image_entry ret; }; 21 template 22 s t r u c t set_super_type < abstract :: image_by_delegation > 23 { typedef abstract ::image_entry ret; }; 24 25 / / p ro p s 26 27 template 28 s t r u c t set_props < category ::image, abstract ::image_by_delegation > 29 : public get_props< category::image, I > 30 { 31 typedef I delegated_type; 32 // FIXME: what about storage_type? 33 } ; 34 35 template 36 s t r u c t set_props < category ::image, abstract :: image_by_delegation > 37 : public get_props< category::image, I > 38 { 39 typedef I delegated_type; 40 typedef is_a image_constness_type; 41 // FIXME: what about storage_type? 42 } ; 43 44 //... 45 46 47 # endif / / ! OLENA_CORE_ABSTRACT_IMAGE_BY_DELEGATION_HH

Figure 1.1: Cryptic C++ code Chapter 2

Island grammars

2.1 Presentation

2.1.1 Definition

Definition 1 ([6]) An island grammar is a grammar that consists of two parts: • detailed productions that describe the language constructs that we are particularly interested in (so called islands) • liberal productions that catch the remainder of the input (so called water).

1 module water 2 imports layout 3 exports 4 s o r t s Water Input Chunk 5 6 context−free syntax 7 Chunk∗ −> Input { cons ("C")} 8 Water −> Chunk { cons ( "W" ) } 9 10 lexical syntax 11 ~[\ \ t \n]+ −> Water {avoid} 12 13 context−free restrictions 14 Water −/− ~[\ \ t \n ]

Figure 2.1: An island grammar written in SDF

Here is the example of the smallest island grammar, that can consider any language. Parsing any file from any language using this small grammar will result on an AST which will be the list of all words in the file. 9 Island grammars

This grammar is the base of all island grammar. The attribute avoid in the lexical production Water is here to explain that we only consider this production rule in last spring.

2.1.2 Concepts These island grammars were created for code refactoring. It enables the programmer to deal with a smaller grammar than the original one. Since we are refactoring some code we don’t need to know the exact grammar, we can concentrate only on the grammar parts in which we have some interest. Then we have to define precisely the parts which present some interest for us. If we forget one or more constructs at the beginning, it will be harder and ugly to had them later. In case of desugaring we are interested only in the sugar constructs (added to the standard language) and the constructs aimed when desugaring. Island grammars are also used when the standard grammar is full of unnecessary informa- tion. Indeed, with an island grammar you only embedded the relevant information, not con- sidering the rest of the input.

2.2 Interests

2.2.1 General Island grammars have several interests, the first one is the speed. A smaller grammar re- duces the parsing time of the input and produces a smaller parse tree. This could be done thanks to the fact we only consider a few rules for the whole input. Then the ast is not very deep so it will be evaluated more quickly. During the parsing, the few amount of rules implies less choices for the parser because like C++ is context-sensitive and very ambiguous, it increases the performances not to consider the whole standard grammar. These grammars help in producing robust and flexible parsers. Indeed every invalid con- struct will be considered as water and will be ignored until the pretty-print phase. These two caracteristics (robustness and flexibility) are always appreciated in an application. Island grammars combine advantages of both lexical an syntactical parsing approaches. They have the accuracy of the syntactical approach and the speed, robustness and flexibility are in- herited from the lexical approach.

2.2.2 Desugaring The interests of using an island grammar to provide sugar to C++ are numerous. First of all, since we are not considering the whole standard grammar of C++, we avoid all the ambiguities it could bring. Then we only write the grammar parts we want to consider, the rest will be considered as water and then won’t even be looked when proceeding the desugaring. This enables us to concentrate on the sugar without being parasited with all the surrounding information in the grammar. The speed aspect is also interesting here. We provided some sugar to help the developer in saving time during the development phase. If the saved time is lost in the desugaring process this is less interesting because you spend the same amount of time in order to obtain a generated file. The only gain here is for the developer if he loves coffee. 2.3 Use 10

2.3 Use

2.3.1 Grammar extensions Here we use an island grammar to add some new constructs to C++. These constructs are provided to simplify the development of applications using efficient C++. Considering that we are not interested with the constructs not entering in the desugaring process or the exact specification of every token, we don’t want to consider the whole grammar of C++. The island grammar enables us to work only on the extensions we wish to provide. Then the only productions we write are corresponding to the language constructs aimed at desugaring added to the sugar constructs.

2.4 Drawbacks

Island grammars are a good way to provide sugar to C++. Then they don’t have only ad- vantages. The major problem is the loss of information occuring during the parsing phase. Of course, like most of the input is considered as water, we lose all the information concerning it. This loss of information as several consequences, it reduces the number of computations we could realize. For example, we have no typing information on the token since there is no type- checker in Transformers. This problem could be overcome by correcting with some part of the standard C++ grammar. The problem here is that if we get to close to the standard we are going to get the ambiguities of this grammar. This is not the only problem, if we complexify the grammar, this will increase the parsing time and the tree size. Two other problems are the robustness and the flexibility. Indeed invalid constructs will be considered as water during the parsing and ignored during the desugaring process. Then we cannot inform the user that his code is wrong and won’t compile. The error advertising is delayed to the compilation. But the will find an error in a generated file, which is very different from the one written by the user. It will be harder for him to retrieve his error with the message he will get from the compiler. Two solutions can help us in handling this process:

• We can compile the code we generate and interprete the error message we get from the compiler to make them clearer for the user.

• We can leave some information to the compiler like the cpp #LINE. This way the compiler could bring understandable error message for the user.

The first solution is not really possible because Transformers is a source to source transforma- tion platform. In the future we can only consider the second solution to help the user in error handling. We must find a way to transmit some information to the compiler. Chapter 3

Cxx_desugar

3.1 Tools

3.1.1 eSDF I chose eSDF [3] to write the island grammar for several reasons.

• First of all I’m used to using it since I work with this tool since January. Then SDF is a very modular environment and like adding sugar is something that can evolve constantly, we need to do it in a very simple way. Also all grammars inside Transformers [8] are written in this language, it helps me to be coherent with the rest of the project.

• This was for the SDF part, now let’s talk about the e in eSDF. I chose to use extended SDF because like I could embedded more information directly in the grammar, it enables to maintain less files. Then all the information concerning a certain production (pretty-print information here) is at the same place and not splitted in several files.

• Almost all the information is embedded in the grammar which is a real advantage, when compiling the program, we extract the information we need to construct all the surround- ing tools (parser, pretty-printer, . . . ).

The pretty-print information is written in Boxed-SDF. This is an extension written by Valentin David that helps the worker to embed the information directly in a SDF grammar. You express your pretty-print information with boxes alignment, you have two types of boxes (horizontal and vertical) that can be imbricated and you adjust some parameters like indentation, vertical or horizontal space concerning a box. The pretty-print information are expressed with the pp attribute in our grammar. You have an example on figure 3.1. This short example shows how I defined a line. Since using an island grammar I lost almost all informaion concerning Water tokens, I needed to express the structure of a line in C++ for the pretty-print phase, otherwise the pretty-printer would write one word by line. 3.1 Tools 12

1 module l i n e 2 imports water layout 3 exports 4 s o r t s Line Macro 5 6 context−free syntax 7 8 Water+ " ; " −> Line { cons ( " Line " ) , 9 pp(H hs=0[_1KW[";"]])} 10 11 Line −> Chunk { cons ( " Line " ) , 12 pp (H[ _1 ] ) } 13 14 Macro Water+ −> Line { cons ( "Mac" ) , 15 pp (H[ _1 H[ _2 ] ] ) } 16 17 lexical syntax 18 19 [\#]~[\ t \ \n]+ −> Macro { prefer }

Figure 3.1: eSDF grammar example

3.1.2 Stratego Stratego is a program transformation language. So it is particularly indicated for what we want to do. Then it is heavily connected with SDF, indeed we can create a module declaring all the constructors we use in our parse tree that correspond to the grammar very easily. Then Stratego is also a very modular environment, it enhances the modularity of the whole application since we can make a grammar module and a Stratego one for each sugar in the process. It is very easy to add a strategy that desugar the whole tree. Another advantage of using Stratego is the concrete syntax. It means that you’re able to write your rules and directly using the syntax of the input file and not the name of the nodes of the tree. This is done declaring some variables. It associates some variable names with some node types. The written code becomes clearer and closer to the original file. This enables the programmer to be more efficient. Indeed the code to write is clearer and lighter, so this also improves the maintainability of the file. We almost express the transformations in the target language. A small example of Stratego code is 3.2. The example 3.3 presents the same code using concrete syntax. 13 Cxx_desugar

1 module eval 2 imports 3 l i b meta 4 5 rules 6 Chg : 7 Meta(Var(n, t, v)) −> MtlVar(l, MVar(t, v), n) 8 where !Ns(["mtl"]) => l

Figure 3.2: A sample of Stratego code

1 module eval 2 imports 3 l i b meta 4 5 rules 6 Chg : 7 |[ "meta" w1 ":" w2 "=" w3 ";"]| −> 8 |[ "mtl::value<" w2 "," w3 ">" w1 ";"]|

Figure 3.3: Concrete syntax in Stratego

3.1.3 SGLR Advantages:

• Even if it’s the thing we absolutely want to avoid for performances reasons, SGLR can parse any LR grammar even the very ambiguous ones. When growing the grammar it is possible that sometimes we introduce some ambiguities in our grammar. So we need a parser that can go farther than LALR.

• SGLR uses some parse tables. The table we give to it is extracted from the grammar. Then when growing the grammar, we never change the parser and there is no need to recompile it every time we add a sugar.

Drawback: SGLR can become very slow when some ambiguities are introduced in the gram- mar. This is a major problem but it forces us to take care of what we write in our grammar. Then most of the disambiguation can be express in the grammar with attributes, restrictions or priorities. Then we can avoid it most of time but not all the time since we are considering C++ code. 3.2 The pipeline 14

3.2 The pipeline

The desugaring process uses a very standard approach of the problem.

• First we have to parse the input file. This is done using SGLR for the reasons expressed just above. After applying SGLR to our input file, we now have an AST representing this file.

• Then we proceed some transformations on the ast, at this step we are not considering all the nodes of the tree (this increases the speed of the treatment). These transformations change certain nodes of the tree in other nodes. At the end we have a tree that when pretty-printed will produce standard C++ code.

• Finally we pretty-print the tree to obtain a standard C++ source file.

There is a figure summarizing this at 3.4

Figure 3.4: The desugaring process 15 Cxx_desugar

3.3 Sugars provided

3.3.1 The meta tag The idea behind the meta tag, is to mark the variables and class hierarchies that should be computed at compile-time. By tagging these values, you enhance the semantical aspect of the code and make it clearer and easier to understand. A "meta" variable is a variable which value is embedded directly in the type. Then you only need to type-check the variable and you know its value. This is often used in Olena. The "meta" hierarchies are templated hierarchies that are instanciated by the compiler. These hierarchies enable the programmer to know the dynamic type of an object statically. This increases the performances of an application since the run-time method-selection is done at compile-time. Without the meta tag, the programmer has to write a lot of template parameters in his code. These templates are not needed from a semantical point of view, these are only a hint to express statically a normally dynamic notion : inheritance. The meta tag does not increase the developing time of an application since the classic con- structs are not so heavy, but like they are used very often and are not really clear, this tag helps in the maintainability of the application. The grammar sample that recognize the meta constructs is 3.5 and the code to desugar it in standard C++ is 3.6

1 module meta 2 imports water layout class 3 exports 4 s o r t s MetaVar MetaClass 5 context−free syntax 6 7 "meta" Water ":" Water "=" Water ";" −> MetaVar { cons ( " Var " ) , 8 pp(H[KW["meta"] _1 KW[":"] _2 KW["="] _3 KW[";"]])} 9 10 " meta " Classdef −> MetaClass { cons ( " Class " ) , 11 pp (H[KW[ " meta " ] _1 KW[ " ; " ] ] ) } 12 13 " meta " S t r u c t d e f −> MetaClass { cons ("Struct"), 14 pp (H[KW[ " meta " ] _1 ] ) }

Figure 3.5: meta.sdf

In this example we see that we are only interested by the Meta nodes in the tree. This sugar is very light and has no repercussion on the environment. There are only local transformations here.

3.3.2 Virtual typedefs The keyword virtual is well-known by C++ users. It enables the user to redefine a method in a sub-class with the guarantee that this redefinition will mask the previous definition for the objects of the subclasses. Then C++ programmers want to have this notion with typedefs too. It is not possible since typedefs are resolved statically and the virtual keyword is deeply dynamic. Then Olena pro- 3.3 Sugars provided 16

1 module eval 2 imports lib meta typedefs 3 r u l e s 4 Chg: Meta(Var(n, t, v)) −> MtlVar(l, MVar(t, v), n) 5 where !Ns(["mtl"]) => l 6 7 Chg: Class2(C(x, Chunks(l))) −> Class2(C(x, Chunks(y))) 8 where l => y 9 10 Chg: Meta1(Class1(C(x, Chunks(y)))) −> 11 TClass(Class1(l, C(x, Chunks(z)))) 12 where ![Temp(Decls([Type1("EXACT" , None)]))] => l 13 ; y => z 14 15 Chg: Meta1(Class1(Herit(x, h, Chunks(y)))) −> 16 TClass(Class1(l, Herit(x, h, Chunks(z)))) 17 where ![Temp(Decls([Type1("EXACT" , None)]))] => l 18 ; y => z 19 20 Chg: TClass(Class1([Temp(Decls(l ))] , MClass(Class2(x)))) −> 21 TClass(Class1([Temp(Decls(l1))], y)) 22 where (l , [Type1("EXACT", None)]) => l1 23 ; x => y

Figure 3.6: meta.str

grammers, since they express their hierarchies in a static way, know statically the dynamic type of the object. We can imagine that with this information it is possible to express virtual typedefs. If we want an upper class to know a typedef defined in a sub-class, we need the sub-class to be instantiated for the upper-class instantiation. But the instantiation of the sub-class, since it inherits from the upper-class, requires the upper-class to be already instantiated. Here we have a cycle were instantiations fail.

To overcome this difficulty, the information concerning virtual typedefs are embedded in a traits hierarchy. The traits hierarchy is a hierarchy that is created in parallel of our own hierarchy whose only role is to contain the information that could not be retrieved in our hierarchy. To maintain this hierarchy in parallel is really heavy in code writing since the inheritance system for the traits hierarchy is very unnatural. These are heavily templated hierarchies, it is also very unnatural, when you want to create a hierarchy, to create a second one only to store information for your first hierarchy. Providing the virtual keyword also for typedefs enables the programmer to save a great amount of time, since he can concentrate on the writing of his hierarchy without thinking about the implementation details. The written code is much closer to the semantical aspect with this keyword used for typedefs. In this sugared C++, we introduce a new keyword abstract for the typedefs. This is the equivalent of pure virtual in C++. Here also the idea is to bring closer the syntax and the thought of the programmer. An abstract typedef is an undefined typedef at this specific level of 17 Cxx_desugar

the hierarchy but that will be defined in the sub-classes that will instantiable.

The grammar part concerning the typedefs is defined in 3.7. Here we only consider the naive typedefs. Others and more complicated definitions of typedefs will be provided soon. During the desugaring process, we are only considering the virtual or abstract typedefs that are inside meta hierarchies. The others won’t be considered and the compiler will signal an error to the programmer. It is inevitable since with an island grammar, we cannot consider the whole input. When finding a virtual typedef in a class, we look for a traits name associated with the class name it inherits from. If it doesn’t exist or the class doesn’t inherit from anyone we create a traits name and associate it to the class name. Then we fill the traits class with the information on the typedefs. We modify the contents of the class and then replace the class definition by the created traits class and the modified class.

1 module typedefs 2 imports water layout 3 exports 4 s o r t s VType AType Type 5 context−free syntax 6 "virtual" "typedef" Water Water ";" −> VType { cons ("V"), 7 pp(H[KW["virtual"] KW["typedef"] _1 _2 KW[";"]])} 8 9 "abstract" "typedef" Water ";" −> AType { cons ("A"), 10 pp(H[KW["virtual"] KW["typedef"] _1 KW["="] KW["0"] KW[";"]])} 11 12 "typedef" Water Water ";" −> Type { cons ("T"), 13 pp(H[KW["typedef"] _1 _2 KW[";"]])}

Figure 3.7: typedefs.sdf

The Stratego code that desugar these virtual typedefs is in 3.8. This code shoud really be transformed with concrete syntax to enhance its comprehensenbility. This code can seem cryptic because we are considering very particular nodes in the tree. The code shown does not represent all treated cases since it doesn’t seem very relevant to show every particular case is desugared. Then I only show one case, the basic one. A class in the middle of a meta hierarchy. To desugar the virtual typedefs, we need to store some information in the environment. We associate class name with traits class name. This could be done very easily thanks to the dy- namic rules of Stratego. 3.4 Future work 18

1 module typedefs 2 imports l i b 3 rules 4 VType: TClass(Class1([Temp(Decls(dl))] , 5 Herit(x, Pub(mc, ph), Chunks(l)))) −> Bloc(Chunks(l1 )) 6 where l => [pasvide | _] 7 ; dl => [nonvide] 10 ; () => (traits, list2) 11 ; !TClass(Class1([Temp(Decls(dl))], 12 Herit(x, Pub(mc, ph), Chunks(list2)))) => class 13 ; ![traits, class] => l1 14 Traitement(|mc, l, x): () −> (traits , list2) 15 where ( 16 mc => x2 17 // Code if the mother class is associated to a traits name. 18 <+ 19 // Traits creation. 20 ) 21 ; rules (Register: x −> x2 ) 22 ; x2 => clist 23 ; clist => tlist 24 ; ( !None ; ?mc2 < !S(x3, Chunks(tlist)) 25 + !Herit1(x3, Pub(x2, mc2), Chunks(tlist))) => class 26 ; ! TClass ( Template−p−S t r u c t d e f ( 27 Temp([Type1("EXACT", None)]), class)) => traits 28 ; list => list2

Figure 3.8: typedefs.str

3.4 Future work

3.4.1 More sugar Of course, these two sugars are not enough to improve significantly the development of applications. Olena programmers want more sugar like: • Functions that take and return types. This enables a more powerful definition of inheri- tance. We can imagine conditional inheritance expressed through a simple if for example. • Constraints on types. Template parameters are not constrained at all. We want to have more control on these parameters to express more powerful things. • Inheritance based on properties. • Multimethods. Olena programmers have to code the static dispatch for multimethods. They want this frontage generated to write the useful code. • ... 19 Cxx_desugar

3.4.2 More checking Obviously, using an island grammar, we have an important loss of information. Then we want to provide some arithmetic for the meta variables, but Transformers has no type-checking so we cannot perform some static computation. Since to improve the written code by the user we need to perform static computation. Introducing type-checking in Transformers will be necessary to develop the sugar. Another aspect to improve is the written code, it should be totally rewritten using concrete syntax to make it clearer and simpler to understand. We should take care about the ambiguities that should be introduced in our grammar when growing it. Even if SGLR is able to parse an input with an ambiguous parse table, it slows it down significantly, however we need to be very quick if we want to have an interest for the programmers. Conclusion

C++ really needs some syntactic sugar to clean the code. When a programmer wants to write some efficient code he has to sacrifice the comprehensibility of the code and this cannot be considered as normal.

Island grammars were well known for code refactoring but were not adopted for sugaring and desugaring a language before. Developing this tool shown that they could fit the problem. They enable the programmer to develop some sugar in a very easy way since when you want to add some sugar, you only have to write new "island" production rules.

They increase the time spent in file parsing and treatment since we are working on a smaller AST where only some nodes have interest. Now we know that using island grammar is a good idea since they enable a very elegant way to ensugar and desugar a grammar.

Now we must grow the tool to fit the real needs of the developers of Olena and Vaucanson. The two sugars already developed show that island grammars are perfect for local transforma- tions and , when using good tools in the developing language (dynamic rules) , you can write transformations that affects the environment very easily and naturally. Actually the experience is to small to take some definitive conclusions. It’s a good start but we need to make more sugar and more realistic tests. The results we already have show that island grammars seem to be a good way to add sugar to a language and need further experiments. Chapter 4

Bibliography

[1] Martin Bravenboer, Arthur van Dam, Karina Olmos, and Eelco Visser. Program transfor- mation with scoped dynamic rewrite rules. Fundamenta Informaticae, 2005. (Conditionally accepted).

[2] Nicolas Burrus, Alexandre Duret-Lutz, Thierry Géraud, David Lesage, and Raphaël Poss. A static C++ object-oriented programming (SCOOP) paradigm mixing benefits of tradi- tional OOP and generic programming. In Proceedings of the Workshop on Multiple Paradigm with OO Languages (MPOOL), Anaheim, CA, USA, October 2003.

[3] Akim Demaille, Thomas Largillier, and Nicolas Pouillard. ESDF: A proposal for a more flexible SDF handling. 2005.

[4] LRDE. Olena, 1999. http://olena.lrde.epita.fr/.

[5] Leon Moonen. Generating robust parsers using island grammars. In Proceedings of the 8th Working Conference on Reverse Engineering, pages 13–22. IEEE Computer Society Press, October 2001.

[6] Leon Moonen. Lightweight impact analysis using island grammars. In Proceedings of the 10th International Workshop on Program Comprehension (IWPC 2002). IEEE Computer Society Press, June 2002.

[7] LRDE.VAUCANSON. http://vaucanson.lrde.epita.fr/.

[8] http://transformers.lrde.epita.fr.

[9] E. Visser and A. van Deursen. Program transformation.org, 2000.

[10] Eelco Visser. Program transformation with Stratego/XT: Rules, strategies, tools, and sys- tems in StrategoXT-0.9. In C. Lengauer et al., editors, Domain-Specific Program Generation, volume 3016 of Lecture Notes in Computer Science, pages 216–238. Spinger-Verlag, June 2004.