<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Centrum Wiskunde &amp; Informatica (CWI)</string-name>
          <email>pvaldera@cwi.nl</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Centrum Wiskunde &amp; Informatica (CWI)</string-name>
          <email>storm@cwi.nl</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Amsterdam</institution>
          ,
          <country country="NL">The Netherlands</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2014</year>
      </pub-date>
      <abstract>
        <p>Rascal is a meta-programming language for processing source code in the broad sense (models, documents, formats, languages, etc.). In this short note we discuss the implementation of the 'TTC'14 FIXML to Java, C# and C++ Case” in Rascal. In particular, we highlight the use of string templates for code generation and relational analysis to deal with dependency-based ordering problems. Rascal is a meta-programming language for source code analysis and transformation [1, 2]. Concretely, it is targeted at analyzing and processing any kind of “source code in the broad sense”; this includes importing, analyzing, transforming, visualizing and generating, models, data files, program code, documentation, etc. Rascal is a functional programming language in that all data is immutable (implemented using persistent data structures), and functional programming concepts are used throughout: algebraic data types, pattern matching, higher-order functions, comprehensions, etc. Specifically for the domain of source code manipulation, Rascal features powerful primitives for parsing (context-free grammars), traversal (visit statement), relational analysis (transitive closure, image, etc.), and code generation (string templates). The standard library includes programming language grammars (e.g., Java), IDE integration with Eclipse, numerous importers (e.g. XML, CSV, YAML, JSON etc.) and a rich visualization framework. In the following sections we discuss the realization of the TTC'14 FIXML case study [3] in Rascal. We conclude the paper with some observations and concluding remarks. All code examples can be found online at: https://github.com/cwi-swat/ttc2014-fixml-case The transformation As proposed in the description of the case study, the solution transformation has been broken down into the following sub transformations: 1. XML text to model of XML metamodel 2. model of XML metamodel to a metamodel of OO programming languages 3. OO metamodel to program text (for different OO programming languages) Below we discuss their implementation. This research was supported by the Netherlands Organisation for Scientific Research (NWO) Jacquard Grant “Next Generation Auditing: Data-Assurance as a service” (638.001.214).</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>Introduction</title>
      <sec id="sec-1-1">
        <title>2.1 Sub transformation 1: XML metamodel to OO metamodel</title>
        <p>This task is readily addressed by Rascal’s standard library, as it contains a metamodel for XML and
(de)serialization functions. Thus, the only code that was necessary to perform this particular
transformartion was:
Node parseXMLDOM(loc src) = parseXMLDOMTrim(readFile(src));</p>
        <p>The parseXMLDOMTrim function parses a string and produces a Node value, conforming to the XML
metamodel. For completeness purposes we present the internal representation of the XML metamodel,
whose essence is captured by these algebraic datatypes:
data Node
= document(Node root)
| attribute(Namespace namespace, str name, str text)
| element(Namespace namespace, str name, list[Node] children)
| charData(str text)
| cdata(str text)
| comment(str text)
| pi(str target, str text)
| entityRef(str name)
| charRef(int code)
;
data Namespace
= namespace(str prefix, str uri)
| none()
;</p>
      </sec>
      <sec id="sec-1-2">
        <title>2.2 Sub transformation 2: XML metamodel to OO metamodel</title>
        <p>The following datatypes capture the structure of the OO metamodel:
data OOModel = oomodel(list[Class] classes);
data Class = class(str name, list[Field] literalFields, list[Field] objFields);
data Field = objField(Type tipe, str name, str altName, list[Field] vals)
| literalField(Type tipe, str name, str altName, str val);
data Type = tipe(str className);</p>
        <p>Note that we have defined an OO metamodel intended to specifically address this particular task. This
means that it is not comprehensive enough to model an arbitrarily complex OO system, but it serves as
the intermediate model from which all the desired output in the context of this task can be generated. For
instance, both data variants of the type Field for representing class fields possess an altName field. This
is needed to represent unambiguous parameters in the case of C++ code, as required by the particular
code style shown in the description of the use case.</p>
        <p>An OOModel consists of a list of classes. Each class has a name, a number of literal fields, and a
number of object fields. A field can be either an object field or a literal field. The difference is that object
fields can have sub fields, whereas literal fields are directly initialized with a (primitive) value. Types
are represented by the Type data type. Note that the difference between literal fields and object fields
is encoded in the Field type; however, for convenience, the class constructor also distinguishes them
explicitly.</p>
        <p>In order to map a FIXML model to an OO model, it was necessary to bridge their conceptual gap
following the informal transformation rules presented in the description of the case study. Consider as an
example the transformation of an XML element to an OO class, specified by the function element2class.
Its formal parameter matches an element from the XML metamodel and deconstructs its fields, i.e., its
name and its children. Using a comprehension, the attributes are extracted from the list of the node’s
children by filtering those that are indeed XML attributes. On the other hand, the class data
constructor receives a name, a list of literal fields and a list of object fields. The attributes2field function
receives the list of nodes known to be attributes, and generates a list of literal fields by using a simple
comprehension.</p>
        <p>Class element2class(element(_, name, children)) =
class(name, attributes2fields(attributes), elements2fields(elements))
when attributes := reverse([a | a &lt;- children, a is attribute]),</p>
        <p>elements := groupElementsByName(children);
list[Field] attributes2fields(list[Node] attributes) =</p>
        <p>[literalField(tipe("String"), name, toAltName(name), val)| attribute(_,name,val)
&lt;attributes];</p>
        <p>The whole XML to OO sub transformation was specified in 75 SLOC of Rascal code.
2.3</p>
      </sec>
      <sec id="sec-1-3">
        <title>OO model to program text</title>
        <p>Once the OO model is produced, the final step is to serialize it as a program in three different OO
languages: Java, C#, and C++. The three transformations are analogous. The main differences are
related to particular idioms of one implementation in respect to the others, particularly in the case of
C++. For instance, although the order in which classes are declared is not relevant in the case of Java
and C#, it matters in the case C++, given its declare-before-use policy. For this reason, we just present
the source code of the Java serialization, and discuss afterwards how we addressed this particularity of
the C++ transformation.
str class2javaClass(class(name, literalFields, objFields)) =
"class &lt;name&gt; {
’ &lt;fields2javaFields(literalFields, objFields)&gt;
’ &lt;name&gt;(){ }
’ &lt;fields2constructor(name, literalFields, objFields)&gt;
’}";
str fields2constructor(str className, list[Field] literalFields, list[Field] objFields)=
"&lt;className&gt;(&lt;toParameters(literalFields, objFields)&gt;){
’ &lt;for (literalField(_, name, _, _) &lt;- literalFields){&gt;
’ this.&lt;name&gt; = &lt;name&gt;;
’ &lt;}&gt;
str fields2javaFields(list[Field] litFields, list[Field] objFields) =
"&lt;for (literalField(tipe, name, _, val) &lt;- litFields){&gt;
’ &lt;tipe.className&gt; &lt;name&gt; = \"&lt;val&gt;\";
’&lt;}&gt;
’&lt;for (objField(tipe, name, _, vals) &lt;- objFields){&gt;
’ &lt;tipe.className&gt; &lt;name&gt; = new &lt;tipe.className&gt;(&lt;toArguments(vals)&gt;);
’&lt;}&gt;";</p>
        <p>The three functions produce strings using Rascal’s string templates. These templates support
multiline strings (margins indicated by ’), string interpolation (escaping expressions with the &lt; and &gt;
characters) and automatic indentation. As a result, model-to-text transformations are very easy to express.</p>
        <p>As mentioned before, the declare-before-use policy of C++ had to be taken into account. We solve
this problem by first sorting the list classes according to their dependencies (topological order):
list[Class] orderClasses(list[Class] classes) =
[classesMap[cName] | cName &lt;- reverse(analysis::graphs::Graph::order(depGraph))]
when classesMap := (className: c | c:class(className, _, _) &lt;- classes),
depGraph := {&lt;className, oName&gt; | class(className, _, oFields) &lt;- classes
, objField(tipe(oName), _, _, _) &lt;- oFields};</p>
        <p>The orderClasses function uses the order function from the graph analysis module (included in the
Rascal standard library), which computes the topological order of the nodes in a graph. Therefore, the
only required task in order to implement the declare-before-use policy was to create a dependency graph
between the classes in the model. The local variable depGraph receives its value from a comprehension
with two generators. This comprehension provides a good example of the advantage of combining
Rascal’s functional nature and its relational calculus support. Given a set of classes, the comprehension
builds a set of tuples (i.e., a binary relation) where its first member is the name of one class obtained
using the first generator, and the second member corresponds to the class name of an object field of such
a class, obtained by means of the second generator. In this way, the dependency graph is computed and
fed to the order function to produce the correct topological order.</p>
      </sec>
    </sec>
    <sec id="sec-2">
      <title>3 Concluding Remarks</title>
      <p>Implementing the FIXML case study in Rascal was straightforward, as Rascal was effectively designed
for supporting the analysis and transformation of source code artifacts. Because of this, many of the more
complex tasks were already solved using the standard library, e.g., XML parsing and topological sorting.
In summary, it took approximately 200 SLOC to implement the pipeline required to output the code
in the three required languages. The most complex part of the assignment was to identify the minimal
subset of an OO metamodel that we needed in order to implement this particular case study. By doing
that, we avoided unnecessary accidental complexity and conceived a metamodel that was described in
just 6 SLOC.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>Paul</given-names>
            <surname>Klint</surname>
          </string-name>
          , Tijs van der Storm &amp; Jurgen
          <string-name>
            <surname>Vinju</surname>
          </string-name>
          (
          <year>2009</year>
          ):
          <article-title>Rascal: A domain-specific language for source code analysis and manipulation</article-title>
          .
          <source>In: SCAM</source>
          , pp.
          <fpage>168</fpage>
          -
          <lpage>177</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Paul</given-names>
            <surname>Klint</surname>
          </string-name>
          , Tijs van der Storm &amp; Jurgen
          <string-name>
            <surname>Vinju</surname>
          </string-name>
          (
          <year>2011</year>
          )
          <article-title>: EASY Meta-programming with Rascal</article-title>
          . In João Fernandes, Ralf Lämmel, Joost Visser &amp; João Saraiva, editors:
          <source>Generative and Transformational Techniques in Software Engineering III, Lecture Notes in Computer Science 6491</source>
          , Springer, pp.
          <fpage>222</fpage>
          -
          <lpage>289</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>K.</given-names>
            <surname>Lano</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Yassipour-Tehrani &amp; K. Maroukian</surname>
          </string-name>
          (
          <year>2014</year>
          ):
          <article-title>The TTC Case study: FIXML to Java, C and C++</article-title>
          .
          <source>In: 7th Transformation Tool Contest (TTC</source>
          <year>2014</year>
          ), EPTCS.
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>