EasyTime++: A case study of incremental domain-specific
language development
Iztok Fister Jr.,∗ Tomaž Kosar,† Iztok Fister,‡ and Marjan Mernik§

Abstract
EasyTime is a domain-specific language (DSL) for measuring time during sports competitions.

arXiv:1303.0722v1 [cs.PL] 4 Mar 2013

A distinguishing feature of DSLs is that they are much more amenable to change, and EasyTime
is no exception in this regard. This paper introduces two new EasyTime features: classifications
of competitors into categories, and the inclusion of competitions where the number of laps must
be dynamically determined. It shows how such extensions can be incrementally added into the
base-language reusing most of the language specifications. Two case studies are presented showing
the suitability of this approach.
To cite paper as follows: I. Jr. Fister, T. Kosar, I. Fister, M. Mernik, EasyTime++: A case
study of incremental domain-specific language development. Information technology and control,
42(1), 77–85, 2013.

∗

University of Maribor, Faculty of electrical engineering and computer science Smetanova 17, 2000 Maribor;

Electronic address: iztok.fister@guest.arnes.si
†

University of Maribor, Faculty of electrical engineering and computer science Smetanova 17, 2000 Maribor;

Electronic address: tomaz.kosar@uni-mb.si
‡

University of Maribor, Faculty of electrical engineering and computer science Smetanova 17, 2000 Maribor;

Electronic address: iztok.fister@uni-mb.si
§

University of Maribor, Faculty of electrical engineering and computer science Smetanova 17, 2000 Maribor;

Electronic address: marjan.mernik@uni-mb.si

1

I.

INTRODUCTION

Domain-specific languages (DSLs) are languages tailored to specific application domain
[1–4]. They offer substantial gains regarding expressiveness and ease of use compared with
general-purpose languages (GPLs) within their domain of application [5–7]. However, DSLs
are more amenable to changes [1, 8] since stakeholders’ requirements frequently change. In
order to design and implement DSLs more easily, we need to develop fully modular, extensible, and reusable language descriptions, whilst some of the descriptions could even be
inferred from DSL programs [9, 10]. The language designer wants to include new language
features incrementally as the programming language evolves. Ideally, a language designer
would like to build a language simply by reusing different language definition modules (language components), such as modules for expressions, declarations, etc., as well as to extend
previous language specifications. In the case of general software development the use of
object-oriented techniques and concepts like encapsulation and inheritance, greatly improves
incremental software development, whilst reusability is even further enhanced using aspectoriented techniques [11]. The object-oriented, as well as the aspect-oriented techniques and
concepts, have also been integrated into programming language specifications [12, 13] making new features more easily implemented. One of such tools, where object-oriented and
aspect-oriented concepts have been incorporated, is the LISA tool [8, 14]. This paper shows
how LISA is used within the incremental development of EasyTime DSL, which has been
developed recently for measuring time at different sports competitions (e.g., triathlon, cycling) [15, 16]. EasyTime DSL has already proved to be successful when used at real sport
events (e.g., World Championship in the double ultra triathlon in 2009, National (Slovenian) Championship in the time-trials for cycles in 2010), so the requirements are changing
quickly. Recent extensions to EasyTime have included the possibility of classifying competitors into different categories, where the number of laps is different for each category, and the
inclusion of competitions where the number of laps can be dynamically determined during
a competition (e.g., biathlon, where the number of extra laps depends on missed shots).
The objective of this paper is to introduce EasyTime++ DSL, which supports these new
extensions, as well as to show how such an extension can be incrementally developed using
the introduced LISA tool.
The structure of this paper is as follows: in Section II an overview of the language

2

composition is presented. Section III briefly introduces EasyTime DSL, whilst the core of this
paper is Section IV, which describes how the extensions in EasyTime++ have been specified
and implemented. Some examples are presented in Section V. The paper is concluded with
Section VI, where a brief overview and word about future work is described.

II.

RELATED WORK

Several kinds of language composition have been identified in the literature [8, 17–24]. In
their recent paper [17], Erdweg et al., point out that language composition has obtained little attention, that it is still insufficiently understood, and that the terminology is confusing
thus indicating that the research is inadequate, as yet. Erdweg et al. identified the language
composeability not as a property of languages themselves, but as a property of language definition (e.g., how language specifications can be composed together). The following types of
language composition have been distinguished in [17]: language extension (which subsumes
also language restriction), language unification, self-extension, and extension composition.
In language extension the specifications of base language B are extended with a new
language specification fragment E, which typically makes little sense when regarded independently from the base language B. Hence, language B is a dominant language, which can
be a DSL or a GPL, and serves as a base for other languages. Language extension, as a kind
of language composition, is denoted as B / E indicating that the base language B has been
extended with the language E. The LISA tool supports language extensions when single
attribute grammar inheritance [8] is employed. As is shown in Section IV, EasyTime++ is a
language extension over the base language EasyTime (EasyTime / EasyTime++). In language unification the composition of language specifications is not based on the dominance
of one language, but is based on equal terms. The dominance of one language over another
does not exist and both language specifications are complete and standalone (note that in
the case of language extension the language specifications for the extended part makes little
sense alone). Language unification, as a kind of language composition, is denoted as L1 ]g L2 ,
describing the language composition of languages L1 and L2 using a glue code g. Since LISA
supports multiple attribute grammar inheritance [8], language unification is easily achieved
by inheriting both language specifications (from L1 and L2 ), where the glue code is specified
as a new language specification fragment. In self-extension the language specifications do
3

not change. The language itself is powerful enough for new extensions to be implemented
using macros, function composition, and libraries that provide domain-specific constructs.
This form of language composition is called ’pure language embedding’ [3]. Functional languages are these languages particularly suitable for self-extension. Self-extension, as a kind
of language composition, is denoted as H ← E indicating that the host language H has
been self-extended with the embedded language E. The last form of language composition
is extension composition, which describes how language specifications also support the
combination of various language compositions. That is showing how different compositions
can work together. This kind of language composition can also be described as high-order
language composition. Language unification allows for such higher-order composition per
se (e.g., L1 ]g (L2 ]h L3 )). Whilst some other useful examples of higher-order language
composition like (B / E1 ) / E2 , and B / (L1 ]g L2 ) can not always be easily achieved. Extension compositions involving language extension and language unification can also be easily
achieved in the LISA tool.

TA 1

CP 0

RUN

BIKE

SWIM

TA 2

3.8 km

180 km

42 km

4x
0.95

4x
45

8x
5.25

CP 1

CP 2

MP 1

CP 3

CP 4

CP 5

CP 6

MP 3

MP 2

CP 7

CP 8

MP 4

FIG. 1: Measuring time in Ironman triathlon.

In addition to LISA, which has been in existence since 1999, there are also other similar
tools (e.g., Phobos [18], JastAdd [19], Silver [20], XMF [21], Tatoo [22], MontiCore [23],
JAYCO [25], UUAG [26]) that enable various language compositions. Note, that the most
well-known tools for syntax and the semantic specification of programming languages, Lex
and Yacc [27], don’t support language composition per se. For example, language extension
is possible by manually changing base language specifications B by invasively adding the
specification for extended language E. Hence, change is done in a non-disciplined manner,
thus prohibiting further reuse of specifications. On the other hand, language composition
4

can be done on top of Lex and Yacc (e.g., [28]). Here, it is desirable to briefly mention
JastAdd [19] and Silver [20], since both are based on Attribute Grammars, as in the LISA
case. JastAdd [19] is centered around object-oriented representation of the abstract syntax
tree (AST). Non-terminals act as abstract super classes and productions act as specialized
concrete subclasses that specify the syntactic structure, attributes, and semantic rules. All
these elements can be inherited, specialized, and overridden within subclasses. The idea of
aspect-orientation in JastAdd is to define each aspect of the language in a separate class
and then weave them together at appropriate places. The JastAdd system is a class weaver:
it reads all the JastAdd modules and weaves the fields and methods into the appropriate
classes during the generation of the AST classes. Developers have the possibility of combining various language specifications following the separation of different language aspects
amongst different classes. Silver [20] uses a concept called ’forwarding’ to achieve modular
language extensions, where the extension construct is translated into semantically equivalent
constructs within the host language. Hence, forwarding only allows those new constructs
that can be expressed as a combination of existing language constructs. Additional Silver
features like: with-clause, auto-copying of inherited attributes, collection attributes, pattern
matching, and type-safe polymorphic lists, allow for the host language to be extended in a
more flexible manner, although still restrictive.

III.

EASYTIME

EasyTime was developed for measuring time during Double ultra triathlon in 2009. At
that time, the organizers of this competition were confronted with the problem of how
to measure the times of competitors within three disciplines using a limited number of
measuring devices. Besides this limitation, measures needed to be reliable and accurate,
especially, because of its long duration. Although the measuring time for the triathlon was
our first specific task, the goal was to develop a DSL for measuring time for any competition.
A domain analysis was performed [15] using feature diagrams [29] with the aim of identifying
common and variable concepts, their relations, and structure of particular concepts. In the
case of EasyTime, the concept race consists of sub-concepts: events (e.g., swimming, cycling,
and running), control points (starting and finishing lines, the number of laps), the measuring
time (updating time and decrementing laps), optional transition area (difference between the
5

finish and start times), and agents (automatic or manual). In the next step, these concepts
were mapped to the context-free grammar non-terminals of EasyTime. Finally, its whole
syntax and semantics were developed [15].
In order to illustrate the power of EasyTime, lets describe the Ironman triathlon, as
presented in Figure 1. This triathlon consists of: 3.8 km swim, 180 km cycling, and a 42
km run. These disciplines run one after another with two interruptions: In the first, those
competitors who have finished with swimming prepare themselves for the cycling, whilst in
the second, those competitors who have finished the cycling prepare themselves for running.
Both interruptions occur within so-called transition areas. Their times spent within these
areas are added to their swimming, cycling, and running times, in order to obtain the total
times of specific competitors.
Typically, the organizers divide those courses on which they run particular disciplines
into laps because of easier management. As can be seen in Figure 1, competitors need
to accomplish 4 laps of swimming, 4 laps of cycling, and 8 laps of running. These laps
represent another demand for the measuring time in such competitions because, besides
the intermediate times of each lap, decrementing also needs to be performed. In order to
reduce the number of measuring devices, a measuring point (MP in Figure 1) at which the
intermediate time is measured and the number of laps is decremented, can be incorporated.
In other words, when the number of laps is zero the last intermediate time becomes the final
time of a specific discipline.
This characteristic of the triathlon is put to profitable use by EasyTime. In fact, EasyTime is a DSL that enables the organizers of sporting competitions to adapt measuring
systems for various kinds of competitions, reduce the number of measuring devices, and
achieve accuracy and reliability. The EasyTime program runs on a measuring system and
employs a set of agents that control the measuring devices. For measuring time during
Inronman, as illustrated in Figure 1, the EasyTime program presented in Program 1 is used.
At the start of Program 1, two agents are defined: The former describes a measuring
device on which manual measuring time is performed on a portable computer by an operator,
whilst the latter denotes a measuring device that automatically tracks an event caused when
a competitor crossing the measuring place, based on RFID technology [30]. Typically, the
automatic measuring place is implemented as a mat that acts as an antenna having two
functions: Firstly, the antenna induces a passive tag that is born by competitor. Secondly,
6

Program 1 EasyTime program for measuring time in Ironman
1: 1 manual ”man.dat”;
// definition of manual agent
2: 2 auto 192.168.225.100; // definition of automatic agent
3: // definition of variables
4: var ROUND1 := 4;
5: var INTER1 := 0;
6: var SWIM := 0;
7: var TRANS1 :=0;
8: var ROUND2 := 4;
9: var INTER2 :=0;
10: var BIKE := 0;
11: var TRANS2 :=0;
12: var ROUND3 := 8;
13: var INTER3 := 0;
14: var RUN := 0;
15: // definition of measuring place 1
16: mp[1] → agnt[1] {
17: (true) → upd INTER1;
18: (true) → dec ROUND1;
19: (ROUND1 == 0) → upd SWIM;
20: }
21: // definition of measuring place 2
22: mp[2] → agnt[1] {
23: (true) → upd TRANS1;
24: }
25: // definition of measuring place 3
26: mp[3] → agnt[2] {
27: (true) → upd INTER2;
28: (true) → dec ROUND2;
29: (ROUND2 == 0) → upd BIKE;
30: }
31: // definition of measuring place 4
32: mp[4] → agnt[2] {
33: (true) → upd INTER3;
34: (ROUND3 == 8) → upd TRANS2;
35: (true) → dec ROUND3;
36: (ROUND3 == 0) → upd RUN;
37: }

this induced tag acts as a transmitter that transmits its identification code to a measuring
device. The transmitted code is detected by the measuring device as an event. This event
is transmitted to the measuring system and recorded into a database by an agent.
After the agents definition in Program 1, a declaration of variables follows. For each
measuring place, two variables are defined in general: an intermediate time INTERx and a
laps counter ROUNDx. The final achievements of a competitor for specific disciplines are
saved within variables SWIM, BIKE, and RUN.
The EasyTime program is completed by definitions of measuring places mp[i], where i
represents its identification number that must be defined uniquely. The measuring place
represents a physical device that is connected to a measuring device. The measuring device
can support more measuring places simultaneously. Conversely to a measuring place, a
control point (CP in Figure 1) represents an event from a logical point of view and denotes
the specific location on the course, where the referees need to track the time information

7

about competitors. As a matter of fact, the control points in EasyTime are directly mapped
into variables. The identification numbers of each agent responsible for transmitting the
events is assigned to each measuring place. For example, manual agent agnt[1] in line 16 of
Program 1 controls the first measuring place.
Before recording the event into a database, a sequence of statements in curly brackets
are interpreted on an abstract machine (AM). These statements are in forms of (predicate)
→ operation, where operation denotes a sequence of instructions that are executed when
the value of predicate returns value true. Typically, two instructions are employed in
EasyTime++: upd and dec. The former update the value of variable in the database,
whilst the latter decrements its value.
Although, DSLs can be implemented in vastly possible ways [1], an appropriate implementation when the end-users are not also the programmers is, a compiler/interpreter approach
[31]. Hence, EasyTime was implemented using a compiler generator tool called LISA [8, 14].
The LISA specifications include lexical, syntax and semantic specifications. Whilst classical
regular expressions and BNF are used for the first two specifications, the third specifications
are based on Attribute Grammars [32]. One of the distinguishing features of a LISA compiler generator is that specifications (lexical, syntax, and semantics) can be easily reused
and extended. An overall view of LISA specifications is given in Listing I.

IV.

EASYTIME++

EasyTime’s formal description was introduced in [15], whilst the mapping of EasyTime’s
denotational semantics into attribute grammars, as well as its implementation, are presented in [16]. Due to requested extensions of EasyTime the language has evolved into
EasyTime++. This section describes the formal specifications that were necessary for the
change. Due to the space constraints, we are unable to include complete specifications.
Interested readers are further referred to [15, 16].
The first small change was done within the semantic domain Runners, which represents
a database of competitors (Listing II). The additional components are now Gender and
Category. Along with Id, RF ID, LastN ame, and F irstN ame, the Gender and Category
regarding competitors have added to the semantic domain Runners. The second, and the
most important change within the semantic domains is how the State, which is the mapping
8

Listing I: Overall view of LISA specifications
language L1 [ extends L2 , ..., LN ] {
lexicon {
[[P] overrides | [P] extends] R regular expr.
..
.
}
attributes type A 1, ..., A M
..
.
rule [[Y] extends | [Y] overrides] Z {
X ::= X11 X12 ... X1p compute {
semantic functions }
..
.
|
Xr1 Xr2 ... Xrt compute {
semantic functions }
;
}
..
.
method [[N] overrides | [N] extends] M {
operations on semantic domains
}
..
.
}

Listing II: Semantic domains in EasyTime++

Category={0, 1, 2, 3 . . .}
Gender={f emale, male}
Runners=(Id × RF ID × LastN ame × F irstN ame × Gender × Category)∗
State=Var → ((Category → Integer) × Truth-Value)

from variables to values, has been modelled (Listing II). Within EasyTime, the State was
a simple mapping: State=Var→Integer, however in EasyTime++ an initial value of an
attribute depends on categories, and a variable, called ’dynamicvar’, can also be initialized
during a run-time. Hence, the State is now modelled as: State = Var → ((Category →
Integer) × Truth-Value)
Let us describe the State using a simple excerpt from EasyTime++ declarations. Three

9

Listing III: Meaning of declarations in EasyTime++

D : Dec → State
D[[var x := a]]s
D[[var x := {cat1 → a1 , cat2 → a2 }]]s
D[[dynamicvar x]]s
D[[D1 ; D2 ]]s

→
=
=
=
=

State
s[x → ((λcategory.a) × f alse)]
s[x → ({cat1 → a1 , cat2 → a2 } × f alse)]
s[x → ((λcategory. ⊥) × true)]
D[[D2 ]](D[[D1 ]]s)

variables were declared within an EasyTime++ program (Program 2). The first variable,
ROU N D1 specifies that all competitors need to complete 50 laps, hence in a database of
competitors the attribute ROU N D1 is set at 50 for all competitors. The second variable,
ROU N D2, specifies that, in a case where a competitor belongs to category = 1, he/she
needs to complete 20 laps, whilst a competitor within category = 2 only needs 10 laps. In
the database of competitors, the attribute ROU N D2 is initialized according to the category.
For all competitors in the first category this attribute will be initialized to 20, and for all
competitors in the second category to 10. The third variable, P EN ALT Y , is a dynamic
variable and its initial value for each competitor will be set during the run-time.
Program 2 Excerpt from EasyTime++ declarations
1: var ROUND1 := 50;
2: var ROUND2 := { (category==1) → 20,
3:

(category==2) → 10 };

4: dynamicvar PENALTY; // definition of dynamic var.

The State in EasyTime++ is mapping which maps variable names (e.g., ROU N D1,
ROU N D2, P EN ALT Y ) into two components. The first component is itself a mapping from
Category to Integer (e.g., 1→20, 2→10), whilst the second component indicates whether
a variable is dynamic or not. To cope with this new model for variables in EasyTime++,
the following LISA methods are needed (note that the mapping from Category to Integer
can be implemented using a hashtable [16], see Program 3).
Since all changes in EasyTime++ are done in a declaration part the semantic function
D (for full description of EasyTime semantic functions please see [15, 16]), which describes
the meanings of the declarations needs to be changed accordingly (Listing III).
10

Program 3 Implementation of EasyTime++ State in LISA
1: method M Var {

class Var {

2:
3:

String name;

4:

Hashtable values;

5:

boolean isDynamic;

6:

Var (String name, Hashtable values,

7:

boolean isDynamic) {

8:

this.name = name;

9:

this.values = values;
this.isDynamic = isDynamic;

10:
11:

}

12:

// Java methods are omitted

13:

...
}

14:
15: }
16:

17: method VarEnvironment {
18:

import java.util.*;

19:

public Hashtable put (Hashtable env, Var aVar) {

20:

env = (Hashtable)env.clone();

21:

env.put(aVar.getName(), aVar);

22:

return env;

23:

} // java method

24: } // Lisa method

Semantic function D maps the syntactic construct Dec, representing the declarations,
into its meaning State → State, which is a mapping from State to State. Note, how
the first component of State is defined in a case where the categories are unspecified (first
equation in Listing III), and in a case of dynamic variables (third equation in Listing III).
In the first equation, it is stated that variable x is mapped to value a regardless of cat-

11

egory. The mapping function λcategory.a is a constant function. The second equation
states that variable x is mapped to different values (e.g., a1 , a2 ) according to different categories (e.g., cat1 , cat2 ), whilst in the third equation, the variable x is mapped to undefined
value ⊥ regardless of category. In the case of dynamic variables the second component of
(Category → Integer) × Truth-Value is true, otherwise it is false.
The aforementioned changes in formal specifications of EasyTime++ also require changes
in the implementation part. Note that changes are required in the lexical part (new keywords
category and dynamicvar, new separator), syntax part (new syntax rules for declarations),
as well as in the semantic part (new semantics for declarations). All the other parts of
EasyTime (e.g., agents, measuring places, statements) [16] are intact and hence can be completely reused. Since EasyTime is implemented in LISA, which supports attribute grammar
inheritance [8], and where lexical, syntax and semantic specifications can be inherited, it was
natural to extend EasyTime specifications written in LISA for implementing EasyTime++,
thus achieving incremental language development. Program 4 shows the LISA specification
of EasyTime++. Note, how all EasyTime specifications have been reused (’language EasyTime++ extends EasyTime’). In the inherited specifications it was necessary to override rule
Dec, which contained syntactic and semantic specifications for declarations, add some new
grammar productions and their semantics (rule Categories), as well as add new attribute
varvalues of type Hashtable, which were attached to the non-terminal CT GRS, and extend regular definitions for Separator and Keyword. Overall less than 70 lines of LISA
specifications have been newly written to obtain the complete compiler for EasyTime++.
Note that this is an example of language extension where language specifications’ fragment
(Program 4) alone does not make any sense and can not exist without base-language specifications (for complete EasyTime specifications in LISA see [16]). Hence, this kind of language
composition can be denoted as EasyTime / EasyTime++.

V.

EXAMPLES

In order to test EasyTime++ DSL two case-studies were performed:
• cyclo-cross Grand-prix, and
• biathlon.
12

Program 4 LISA specification of EasyTime++
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:

language EasyTime++ extends EasyTime {
lexicon {
extends Separator ,
extends Keyword category — dynamicvar
}
attributes Hashtable *.varvalues;
rule extends Start {
compute { }
}
rule overrides Dec {
DEC ::= var #Id := #Int ; compute {
// category is not specified; isDynamic=false
DEC.outState = put(DEC.inState,
new Var(#Id.value(),
put(new Hashtable(), ”0”,
Integer.valueOf(#Int.value()).intValue()), false));
};
DEC ::= dynamicvar #Id ; compute {
// category can not be specified; isDynamic=true
DEC.outState = put(DEC.inState,
new Var(#Id.value(), null, true));
};
DEC ::= var #Id := { CTGRS } ; compute {
// categories are specified and can’t be dynamic
DEC.outState = put(DEC.inState,
new Var(#Id.value(), CTGRS.varvalues, false));
};
}
rule Categories {
CTGRS ::= ( category == #Int ) → #Int , CTGRS
compute {
CTGRS[0].varvalues = put(CTGRS[1].varvalues,
#Int[0].value(),
Integer.valueOf(#Int[1].value()).intValue());
};
CTGRS ::= ( category == #Int ) → #Int compute {
CTGRS.varvalues = put(new Hashtable(),
#Int[0].value(),
Integer.valueOf(#Int[1].value()).intValue());
};
}
...
// LISA methods
}

13

The former was experienced in practice, whilst the latter could be taken as proof of
concept. In the rest of this section, both case-studies are discussed in detail.

A.

Case-study 1: Cyclo-cross Grand-Prix

This case-study tested the introduction of categories in EasyTime++. Cyclo-cross is a
relatively new sport that typically takes place in winter and is dedicated to cycle road-riders
who are preparing for the new season. Races usually consist of several laps of a short course
featuring pavements, wooded trails, grass, steep hills, and obstacles.
In this case-study, one lap of 2.5 km was used (Figure 2). According to the number of
laps, the competitors were divided into three categories, as follows:
• 4 laps: junior men and women up to 15 years old (U-15),
• 6 laps: junior men and women up to 19 years old (U-19), and
• 9 laps: absolute categories (U-23, Elite, Masters).
In order to make the competition more interesting, the organizers allowed all the competitors onto the course simultaneously. Only one measuring device with two measuring
places was needed for measuring this competition because the course passed at one location.
Here, the intermediate times of laps were measured and, thereby, decremented the laps’
counters of specific competitors. When the laps counter reached zero the finish time of the
competitor was reported. However, how many laps to go depended on the category to which
the specific competitor belonged.
The EasyTime++ program for measuring time in this competition can be seen by Program 5. Note that here both measuring places, i.e., mats, were laid so that the whole length
of the finish line was captured. In line with this, a competitor can cross either of both mats.
As a result, the programs for both measuring devices are the same, and work in parallel.

14

FIG. 2: Track layout of the cyclo-cross competition.

Program 5 EasyTime++ program for measuring time in cyclo-cross competition
1: 2 auto 192.168.225.100; // definition of agent
2: var BIKE := 0;
3: var ROUND1 := { (category==1) → 4,

(category==2) → 6, (category==3) → 9 };

4:

5: // definition of measuring place 1
6: mp[1] → agnt[2] {
7:

(true) → dec ROUND1;

8:

(ROUND1 == 0) → upd BIKE;

9: }
10: // definition of measuring place 2
11: mp[2] → agnt[2] {
12:

(true) → dec ROUND1;

13:

(ROUND1 == 0) → upd BIKE;

14: }

In summary, measuring time in cyclo-cross performed well with EasyTime++. Although
the organizers prepared three different lengths of courses, six different lists of results were

15

obtained according to gender. Fortunately, in our case the gender could be handled by a
database system, whilst the EasyTime++ program was unaware of it.

B.

Case-study 2: Biathlon

A biathlon was the second case-study for EasyTime++. Biathlon refers specifically to
the winter sport that combines cross-country skiing and rifle shooting. As can be seen from
Figure 3, competitors start with skiing. Skiing is interrupted by rifle shooting. Typically,
biathlon consists of 4 laps of skiing. The shooting appears close to the end of a lap. Two
positions for competitors are allowed when shooting, i.e., prone and standing. Interestingly,
the number of missed shoots is penalized by the additional number of penalty laps. Note
that the time spent within the penalty laps are added to the total time of the competitor.
The time of the penalty lap is typically taken to be between 20-30 seconds.
The EasyTime++ program for measuring time in biathlon can be seen by Program 6.
Three measuring devices are needed to cover this competition. Each measuring device
realizes one measuring place. Moreover, each measuring place also represents a control
point. In contrast to Ironman, in a biathlon time spent in penalty loops is of no interest in
the preferred race. Here, only the total time of competitor is important.

CP 0

CP 1

CP 2

CP 3

PENALTY

MP 1

MP 2

MP 3

4x

FIG. 3: Measuring time in biathlon competitions.

In summary, the first device represents the special measuring device for counting hits.
The agent assigned to this device puts the number of missed hits into the database variable
PENALTY, dynamically. Note that this device is treated in EasyTime like an ordinary
measuring device. The second measuring device is dealt with by counting the penalty laps,
whilst the third device measures the final time.

16

Program 6 EasyTime++ program for measuring time in biathlon competition
1 auto 192.168.225.110; // definition of agent 1
2 auto 192.168.225.100; // definition of agent 2
var ROUND := 4;
var RUN := 0;
dynamicvar PENALTY; // definition of dynam.variable
// definition of measuring place 1
mp[1] → agnt[1] {
(true) → upd PENALTY;
}
// definition of measuring place 2
mp[2] → agnt[2] {
(true) → dec PENALTY;
}
// definition of measuring place 3
mp[3] → agnt[2] {
(true) → dec ROUND;
(ROUND == 0) → upd RUN;
}

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:

VI.

CONCLUSIONS

Easy language composition is still an open-issue within programming language research.
In particular, a new young field of software language engineering is of interest regarding engineering principles when constructing new languages, whether general-purpose or domainspecific. A language designer would like to build a new language simply by composing
different components and/or extending previous components. This paper has presented
EasyTime++ DSL as a language extension of EasyTime, where the base language specifications written in the LISA compiler generator have been extended with new features,
thus enabling the introduction of categories into competitions, and those new competitions
where the number of laps is dynamically determined. The implemented multiple attribute
grammar inheritance in LISA enables easy language composition since lexical, syntax, and
semantic specifications can be reused and extended. In such a manner, an incremental language development using LISA has been demonstrated. The suitability of EasyTime++ was
shown in two case studies: cyclo-cross Grand-prix and a biathlon. More extensive experimental work, which would include other types of language compositions and more DSLs, is

17

also planned in the future.

[1] M. Mernik, J. Heering, A. M. Sloane. When and how to develop domain-specific languages. ACM Computing Surveys, 2005, 37(4), 316–344.
[2] A. van Deursen, P. Klint, J. Visser. Domain-specific languages: an annotated bibliography. ACM SIGPLAN Notices, 2000, 35(6), 26–36.
[3] P. Hudak. Building domain-specific embedded languages. ACM Computing Surveys, 1996,
28(4es).
[4] M. Fowler. Domain Specific Languages. Addison-Wesley Professional, 2010.
[5] M. J. Varanda Pereira, M. Mernik, D. da Cruz, P. R. Henriques. Program comprehension for domain-specific languages. Computer Science and Information Systems, 2008,
5(2), 1–17.
[6] T. Kosar, N. Oliveira, M. Mernik, M. J. Varanda Pereira, M. Črepinšek, D. da
Cruz, P. R. Henriques. Comparing General-Purpose and Domain-Specific Languages: An
Empirical Study. Computer Science and Information Systems, 2010, 7(2), 247–264.
[7] T. Kosar, M. Mernik, J. C. Carver. Program comprehension of domain-specific and
general-purpose languages: comparison using a family of experiments. Empirical software
engineering, 2012, 17(3), 276–304.
[8] M. Mernik, V. Žumer. Incremental programming language development. Computer Languages, Systems and Structures, 2005, 31(1), 1–16.
[9] D. Hrnčič, M. Mernik, B. R. Bryant. Embedding DSLs into GPLs: A Grammatical
Inference Approach. Information Technology and Control, 2011, 40(4), 307–315.
[10] D. Hrnčič, M. Mernik, B. R. Bryant, F. Javed. A memetic grammar inference algorithm
for language learning. Applied Soft Computing, 2012, 12(3), 1006–1020.
[11] G. Kiczales. Aspect-oriented programming. ACM Computing Surveys, 1996, 28(4), Article
No. 154.
[12] P. Klint, T. van der Storm, J. J. Vinju. Term rewriting meets aspect-oriented programming. Processes, Terms and Cycles: Steps on the Road to Infinity. Springer-Verlag, 2005,
88–105.
[13] M. Mernik, D. Rebernak. Aspect-Oriented Attribute Grammars. Electronics and Electrical

18

Engineering, 2011, 10(116), 99–104.
[14] P. R. Henriques, M. J. Varanda Pereira, M. Mernik, M. Lenič, J. Gray, H. Wu.
Automatic generation of language-based tools using LISA. IEE Proceedings - Software Engineering, 2005, 152(2), 54–69.
[15] I. Jr. Fister, I. Fister, M. Mernik, J. Brest. Design and implementation of domainspecific language Easytime. Computer Languages, Systems and Structures, 2011, 37(4), 276–
304.
[16] I. Jr. Fister, M. Mernik, I. Fister, D. Hrnčič. Implementation of EasyTime Formal
Semantics using a LISA Compiler Generator. Computer Science and Information Systems,
2012, 9(3): 1019–1044.
[17] S. Erdweg, P. G. Giarrusso, T. Rendel. Language Composition Untangled. In: Proceedings of Workshop on Language Descriptions, Tools and Applications (LDTA’12). Published online at http://www.informatik.uni-marburg.de/∼seba/publications/languagecomposition. pdf,
2012.
[18] A. Granicz, J. Hickey. Phobos: A front-end approach to extensible compilers. In: Proceedings of the 36th Annual Hawaii International Conference on System Sciences (HICSS36),
2003.
[19] G. Hedin, E. Magnusson. JastAdd: an aspect-oriented compiler construction system. Science of Computer Programming, 2003, 47(1), 37–58.
[20] E. Van Wyk, D. Bodin, J. Gao, L. Krishnan. Silver: An extensible attribute grammar
system. Science of Computer Programming, 2010, 75(1), 39–54.
[21] T. Clark, P. Sammut, J. Willans. Superlanguages: Developing languages and applications
with XMF. Published online at hhtp://bit.ly/HiTOKp, 2008.
[22] J. Cervelle, R. Forax, G. Roussel. A simple implementation of grammar libraries. Computer Science and Information Systems, 2007, 4(2), 65–77.
[23] H. Krahn, B. Rumpe, S. Voelkel. MontiCore: Modular development of textual domain
specific languages. In: Proceedings of the 30th International Conference on Software Engineering (SLE 2008), 2008, 925–926.
[24] A. Stonis, D. Rubliauskas, J. Blonskis. Mapping Syntax Extensions. Information Technology and Control, 2002, 24(3), 35–48.
[25] J. Porubän, M. Forgáč, M. Sabo, M. Bı̀hálek. Annotation Based Parser Generator.

19

Computer Science and Information Systems, 2010, 7(2), 291–307.
[26] M.

Viera,

S.

D.

Swierstra,

A.

Middelkoop.

How to make Attribute Grammars First-Class. In:
Language

Descriptions,

Tools

and

Applications

UUAG

Meets

AspectAG:

Proceedings of Workshop on

(LDTA’12).

Published

online

at

http://www.cs.uu.nl/research/techreps/repo/CS-2011/2011-029.pdf, 2012.
[27] D. Brown, J. Levine, T. Mason. lex & yacc. O’Reilly Media, 2nd Edition, 1992.
[28] X. Wu, B.R. Bryant, J. Gray, M. Mernik. Component-based LR parsing. Computer
Languages, Systems and Structures, 2010, 36(1), 16–33.
[29] V. Štuikys, R. Damaševicius. Measuring Complexity of Domain Models Represented by
Feature Diagrams. Information Technology and Control, 2009, 38(3), 179–187.
[30] K. Finkenzeller. RFID Handbook. John Wiley & Sons, 2010.
[31] T. Kosar, P. E. Martı́nez López, P. A. Barrientos, M. Mernik. A Preliminary Study on
Various Implementation Approaches of Domain-Specific Language. Information and Software
Technology, 2008, 50(5), 390–405.
[32] J. Paakki. Attribute Grammar Paradigms - A High-Level Methodology in Language Implementation. ACM Computing Surveys, 1995, 27(2), 196–255.
Updated 3 March 2013.

20

