2008 A Case Study in Grammar Engineering
2008 A Case Study in Grammar Engineering
Introduction
the specific case of our VDM grammar development project. We describe the
development process and its intermediate and final deliverables. We discuss related work in Section 4, including comparison to earlier grammar engineering
case studes [2, 3]. In Section 5 we summarize our contributions and identify future challenges.
grammar
parser
pretty-printer
Abstract
Syntax
serialization
deserialization
Traversal
Support
Grammar evolution
Grammars for sizeable languages are not created instantaneously, but through
a prolonged, resource consuming process. After an initial version of a grammar
has been created, it goes through an evolutionary process, where piece-meal
modifications are made at each step. After delivery of the grammar, evolution
may continue in the form of corrective and adaptive maintenance.
A basic instrument in making such evolutionary processes tractable is version
control. We have chosen the Concurrent Versions System (CVS) as the tool to
support such version control [13].
As alternative, GDK [14] could be used enabling the documentation of changes
as a set of transformations. Although this is an interesting academic approach
we preferred the use of more practical and standard tool.
In grammar evolution, different kinds of transformation steps occur:
Recovery: An initial version of the grammar may be retrieved by reverse engineering an existing parser, or by converting a language reference manual,
Grammar metrics
Structure metrics
TIMP Tree impurity (%)
CLEV Normalized count of levels (%)
NSLEV Number of non-singleton levels
DEP Size of largest level
HEI Maximum height
Fig. 3. Structure metrics for grammars.
Size, complexity, and structure metrics Figure 2 lists a number of size and
complexity metrics for grammars. These metrics are defined for BNF in [15].
The number of terminals (TERM) and non-terminals (VAR) are simple metrics
applicable equally to BNF and SDF grammars. McCabes cyclomatic complexity
(MCC), originally defined for program complexity, was adapted for BNF grammars, based on an analogy between grammar production rules and program
procedures. Using the same analogy, MCC can be extended easily to cover the
operators that SDF adds to BNF.
The average size of right-hand sides (AVS) needs to be adapted to SDF with
more care. In (E)BNF the definition of AVS is trivial: count the number of
terminals and non-terminals on the right-hand side of each grammar rule, sum
these numbers, and divide them by the number of rules. In SDF, this definition
can be interpreted in two ways, because each non-terminal can have several
productions associated to it. Therefore, we decided to split AVS into two separate
metrics: average size of right-hand sides per production (AVS-P) and average
size of right-hand sides per non-terminal (AVS-N). For grammars where each
non-terminal has a single production rule, as is the case for (E)BNF grammars,
these metrics will present the same value. For SDF grammars, the values can be
different. While the AVS-N metric is more appropriate to compare with other
formalisms (like BNF and EBNF), the AVS-P metric provides more precision.
Tree impurity (TIMP) measures how much the flow graph deviates from a
tree, expressed as a percentage. A tree impurity of 0% means that the graph is
a tree and a tree impurity of 100% means that is a fully connected graph.
Normalized count of levels (CLEV) expresses the number of nodes in the level
graph (graph of strongly connected components) as a percentage of the number
of nodes in the flow graph. A normalized count of levels of 100% means that
there are as many levels in the level graph as non-terminals in the flow graph.
In other words, there are no circular connections in the flow graph, and the level
graph only contains singleton components. A normalized count of levels of 50%
means that about half of the non-terminals of the flow graph are involved in
circularities and are grouped into non-singleton components in the level graph.
Number of non-singleton levels (NSLEV) indicates how many of the grammar
strongly connected components (levels) contain more than a single non-terminal.
Size of the largest level (DEP) measures the depth (or width) of the level
graph as the maximum number of non-terminals per level.
Maximum height (HEI) measures the height of the level graph as the longest
vertical path through the level graph, i.e. the biggest path length from a source
of the level graph to a sink.
Halstead metrics The Halstead Effort metric [17] has also been adapted for
(E)BNF grammars in [15]. We compute values not only for Halsteads effort
metric but also for some of its ingredient metrics and related metrics. Figure 4
shows a full list. The essential step in adapting Halsteads metrics to grammars is
to interpret the notions of operand and operator in the context of grammars. For
more details about the interpretation from BNF to SDF we refer again to [16].
The theory of software science behind Halsteads metrics has been widely
questioned. In particular, the meaningfulness and validity of the effort and time
metrics have been called into question [18]. Below, we will still report HAL, for
purposes of comparison to data reported in [15].
Disambiguation metrics In SDF, disambiguation constructs are provided in
the same formalism as the syntax description itself. To quantify this part of SDF
grammars, we defined a series of metrics, which are shown in Figure 5. These
metrics are simple counters for each type of disambiguation construct offered by
the SDF notation.
Disambiguation metrics
FRST Number of follow restrictions
ASSOC Number of associativity attributes
REJP Number of reject productions
UPP Number of unique productions in priorities
Fig. 5. Disambiguation metrics for grammars.
2.4
Grammar testing
In software testing, a global distinction can be made between white box testing
and black box testing. In black box testing, also called functional or behavioral
testing, only the external interface of the subject system is available. In white box
testing, also called unit testing, the internal composition of the subject system
is taken into consideration, and the individual units of this composition can be
tested separately.
In grammar testing, we make a similar distinction between functional tests
and unit tests. A functional grammar test will use complete files as test data.
The grammar is tested by generating a parser from it and running this parser
on such files. Test observations are the success or failure of the parser on a
input file, and perhaps its time and space consumption. A unit test will use
fragments of files as test data. Typically, such fragments are composed by the
grammar developer to help him detect and solve specific errors in the grammar,
and to protect himself from reintroducing the error in subsequent development
iterations. In addition to success and failure observations, unit tests may observe
the number of ambiguities that occur during parsing, or the shape of the parse
trees that are produced.
For both functional and unit testing we have used the parse-unit utility [19].
Tests are specified in a simple unit test description language with which it is
possible to declare whether a certain input should parse or not, or that a certain
input sentence should produce a specific parse tree (tree shape testing). Taking
such test descriptions as input, the parse-unit utility allows batches of unit
tests to be run automatically and repeatedly.
2.5
Coverage metrics
To determine how well a given grammar has been tested, a commonly used
indicator is the number of non-empty lines in the test suites.
A more reliable instrument to determine grammar test quality is coverage
analysis. We have adopted the rule coverage (RC) metric [20] for this purpose.
The RC metric simply counts the number of production rules used during parsing
of a test suite, and expresses it as a percentage of the total number of production
rules of the grammar.
SDF allows two possible interpretations of RC, due to the fact that a single
non-terminal may be defined by multiple productions. (Above, we discussed a
similar interpretation problem for the AVS metric.) One possibility is to count
Language Though we are interested in eventually developing grammars for various existing VDM dialects, such as IFAD VDM and VDM++, we limited the
scope of the initial project to the VDM-SL language as described in the ISO
VDM-SL standard [23].
Grammar shape Not only should the parser generate the VDM-SL language as
defined in the standard, we also want the shape of the grammar, the names of the
non-terminals, and the module structure to correspond closely to the grammar.
We want to take advantage of SDFs advanced regular expression-style constructs
wherever this leads to additional conciseness and understandability.
Parsing and parse trees Though the grammar should be suitable for generation
of a wide range of tool components and tools, we limited the scope of the initial
project to development of a grammar from which a GLR parser can be generated.
The generated parser should be well-tested, exhibit acceptable time and space
consumption, parse without ambiguities, and build abstract syntax trees that
correspond as close as possible to the abstract syntax as defined in the standard.
Planned deliverables Based on the defined scope and priorities, a release plan
was drawn up with three releases within the scope of the initial project:
Initial grammar Straightforward transcription of the concrete syntax BNF
specification of the ISO standard into SDF notation. Introduction of SDFs
regular expression-style constructs.
Disambiguated grammar Addition of disambiguation information to the grammar, to obtain a grammar from which a non-ambiguous GLR parser can be
generated.
Refactored grammar Addition of constructor attributes to context-free productions to allow generated parsers to automatically build ASTs with constructor names corresponding to abstract syntax of the standard. Changes
in the grammar shape to better reflect the tree shape as intended by the
abstract syntax in the standard.
The following functionalities have explicitly been kept outside the scope of the
initial project, and are planned to be added in follow-up projects:
Haskell front-end3 . Including generated support for parsing, pretty-printing,
AST representation, AST traversal, marshalling ASTs to XML format and
back, marshalling of ASTs to ATerm format and back.
Java front-end. Including similar generated support.
IFAD VDM-SL extensions, including module syntax.
VDM object-orientation extension (VDM++ ).
Section 5.2 discusses some of this future work in more detail.
3.2
To accurately keep track of all grammar changes, a new revision was created for
each grammar evolution step. This led to the creation of a total of 48 development
versions. While the first and the latest release versions (initial and refactored)
correspond to development versions 1 and 48 of the grammar, respectively, the
intermediate release version (disambiguated) corresponds to version 32.
3
At the time of writing, a release with this functionality has been completed.
The initial grammar The grammar was transcribed from the hardcopy of the
ISO Standard [23]. In that document, context-free syntax, lexical syntax and disambiguation information are specified in a semi-formal notation. Context-free
syntax is specified in EBNF, but the terminals are specified as mathematical
symbols. To translate the mathematical symbols to ASCII symbols an interchange table is provided. Lexical syntax is specified in tables by enumerating
the possible symbols. Finally, disambiguation information is specified in terms
of precedence in tables and equations.
Apart from changing syntax from EBNF to SDF and using the interchange
table to substitute mathematical symbols for its parseable representation, the
following was involved in the transcription.
Added SDF constructs Although a direct transcription from the EBNF specification was possible, we preferred to use SDF specific regular-expressionstyle constructs. For instance consider the following excerpt from the ISO
VDM-SL EBNF grammar:
product type = type, "*", type, { "*", type} ;
Both excerpts define the same language. Apart from the syntactic differences
from EBNF to SDF, the difference is that SDF has special constructs that
allows definition of the repetition of a non-terminal separated by a terminal.
In this case, the non-terminal Type appears at least two times and is always
separated by the terminal "*".
Detected top and bottom non-terminals To help the manual process of
typing the grammar a small tool was developed to detect top and bottom
non-terminals. This tool helped to detect typos. More than one top nonterminal, or a bottom non-terminal indicates that a part of the grammar is
not connected. This tool provided a valuable help not only in this phase but
also during the overall development of the grammar.
Modularized the grammar (E)BNF does not support modularization. The
ISO Standard separates concerns by dividing the EBNF rules over sections.
SDF does support modules, which allowed us to modularize the grammar
following the sectioning of the ISO standard. Also, another small tool was
implemented to discover the dependencies between modules.
Added lexical syntax In SDF, lexical syntax can be defined in the same grammar as context-free syntax, using the same notation. In the ISO standard,
lexical syntax is described in an ad hoc notation resembling BNF, without
clear semantics. We interpreted this lexical syntax description and converted
it into SDF. Obtaining a complete and correct definition required renaming
some lexical non-terminals and providing additional definitions. Detection
of top and bottom non-terminals in this case helped to detect some inconsistencies in the standard.
Grammar metrics
300
250
200
VAR
HAL (K)
CLEV
150
100
50
0
1
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 45 46 47 48
Fig. 6. The evolution of VAR, HAL, and CLEV grammar metrics during development.
The x-axis represents the 48 development versions.
This is conform to expectation, since all keywords and symbols of the language
are present from the first grammar version onward.
The initial number of 161 non-terminals (VAR) decreases via 118 after disambiguation to 71 after refactoring. These numbers are the consequence of changes
in grammar shape where non-terminals are replaced by their definition. In the
disambiguation phase (43 non-terminals removed), such non-terminal inlining
was performed to make formulation of the disambiguation information possible,
or easier. For instance, after inlining, simple associativity attributes would suffice
to specify disambiguation, while without inlining more elaborate reject productions might have been necessary. In the refactoring phase (47 non-terminals removed), the inlinings performed were mainly removals of injections. These were
performed to make the grammar easier to read, more concise, and suitable for
creation of ASTs closer to the abstract syntax specification in the standard.
The value of the McCabe cyclomatic complexity (MCC) is expected to remain
constant. However the value decreases by 2 during disambiguation, meaning that
we eliminated two paths in the flow graph of the grammar. This was caused
by refactoring the syntax of product types and union types in similar ways
required for disambiguation purposes. In case of product types, the following
two production rules:
ProductType
-> Type
{ Type "*" }2+ -> ProductType
-> Type
For union types, the same replacement was performed. The language generated
by the grammar remained the same after refactoring, but disambiguation using
priorities became possible. In refactorings, MCC remains constant as expected.
The average rules size metrics, AVS-N and AVS-P increase significantly.
These increases are also due to inlining of non-terminals. Naturally, when a
non-terminal with a right-hand size of more than 1 is inlined, the number of
non-terminals decreases by 1, and the size of the right-hand sides of the productions in which the non-terminal was used goes up. The increase of AVS-N
is roughly by a factor of 2.4, while the increase of AVS-P is by a factor of 1.4.
Given the decrease of VAR, increase in AVS-N is expected. However, the limited
increase in AVS-P indicates that inlining did not produce overly large production
rules.
Halstead metrics The value of the Halstead Effort metric (HAL) fluctuates
during development. It starts at 228K in the initial grammar, and immediately
rises to 255K. This initial rise is directly related to the removal of 32 nonterminals. The value then rises more calmly to 265K, but drops again abruptly
towards the end of the disambiguation phase, to the level of 236K. During refactoring, the value rises again to 255K, drops briefly to 224K, and finally stabilizes
at 256K. Below, a comparison of these values with those of other grammars will
be offered. The use of Halstead is for comparison purpose only and we attach no
conclusions.
Structure metrics Tree impurity (TIMP) measures how much the grammars
flow graph deviates from a tree, expressed as a percentage. The low values for
this measure indicates that our grammar is almost a tree, or, in other words,
that complexity due to circularities is low. As the grammar evolves, the tree
impurity increases steadily, from little more than 1%, to little over 3%. This
development can be attributed directly to the non-terminal inlining that was
performed. When a non-terminal is inlined, the flow graph becomes smaller, but
the number of cycles remains equal, i.e. the ratio of the latter becomes higher.
Normalized count of levels (CLEV) indicates roughly the percentage of modularizability, if grammar levels (strongly connected components in the flow graph)
are considered as modules. Throughout development, the number of levels goes
down (from 58 to 40; values are not shown), but the potential number of levels, i.e. the number of non-terminals, goes down more drastically (from 161 to
71). As a result, CLEV rises from 34% to 53%, meaning that the percentage of
modularizability increases.
The number of non-singleton levels (NSLEV) of the grammar is 4 throughout
most of its development, except at the end, where it goes down to 3. Inspection
of the grammar learns us that these 4 levels roughly correspond to Expressions,
Statement, Type and StateDesignators. The latter becomes a singleton level towards the end of development due to inlining.
The size of the largest grammar level (DEP) starts initially very high at 69
non-terminals, but drops immediately to only 39. Towards the end of development, this number drops further to 27 non-terminals in the largest level, which
corresponds to Expressions. The decrease in level sizes is directly attributable
to inlining of grammar rules involved in cycles.
The height of the level graph (HEI) is 16 throughout most of the evolution
of the grammar, but sinks slightly to 14 towards the end of development. Only
Fig. 7. The evolution of the ASSOC and UPP disambiguation metrics compared with
the evolution of the number of productions (PROD). The x-axis represents the 48
development versions.
Table 2. Grammar metrics for VDM and other grammars. The italicized grammars
are in BNF, and their metrics are reproduced from [15]. The remaining grammars are
in SDF. Rows have been sorted by Halstead effort (HAL), reported in thousands.
Grammar
term var mcc avs-n avs-p hal timp clev nslev dep
Fortran 77
21 16 32
8.8
3.4 26 11.7 95.0
1
2
ISO C
86 65 149 5.9
5.9 51 64.1 33.8
3
38
Java v1.1
100 149 213 4.1
4.1 95 32.7 59.7
4
33
AT&T SDL
83 91 170 5.0
2.6 138 1.7 84.8
2
13
ISO C++
116 141 368 6.1
6.1 173 85.8 14.9
1
121
ECMA Standard C# 138 145 466 4.7
4.7 228 29.7 64.9
5
44
ISO VDM-SL
138 71 232 10.4 3.3 256 3.0 52.6
3
27
VS Cobol II
333 493 739 3.2
1.9 306 0.24 94.4
3
20
VS Cobol II (alt)
364 185 1158 10.4 8.3 678 1.18 82.6
5
21
PL/SQL
440 499 888 4.5
2.1 715 0.3 87.4
2
38
hei
7
13
23
15
4
28
14
27
15
29
similar syntax (let, def, if, foreach, exits, etc. expressions) which do not have
associativity information.
From versions 18 to 24 the number of production in priorities grows simultaneously while the total number of productions decreases. This shows that, once
more, disambiguation was only enabled by injection removal or by inlining.
Although not shown in the chart, from the 24th version until the 32th disambiguation was continued by adding lookahead restrictions and reject productions.
In this phase lexicals were disambiguated by keyword reservation or by preferring the longer match in lexical recognition. For that reason, the total number
of productions remains practically unchanged.
error prune and harder to understand. This can be revealed by high values of
the TIMP metric.
In terms of Halstead effort, our VDM-SL grammar ranks quite high, only
behind the grammars of the giant Cobol and PL/SQL languages.
Discussion As previously observed, different metrics can play different roles,
namely validation, quality improvement, productivity and comparison. Examples
of validation are MCC and TERM which are expected to remain constant under
semantics preserving operations such as disambiguations and refactorings. If
deviations are noticed, inspection is needed to check no errors were committed.
Examples of quality improvement are VAR, DEP and HEI. Lower values mean a
more compact and easier to understand grammar. The increase of TIMP can be
seen as quality loss, but is explainable against background of strongly decreasing
VAR, so no actual quality is lost. Examples of productivity are disambiguation
metrics such as ASSOC and UPP. Finally, for comparison in order to be able to
quantitatively and qualitatively rank different grammars.
3.4
Test suites
Integration test suite The body of VDM-SL code that strictly adheres to the
ISO standard is rather small. Most industrial applications have been developed
with tools that support some superset or other deviation from the standard, such
as VDM++ . We have constructed an integration test suite by collecting specifications from the internet4 . A preprocessing step was done to extract VDM-SL
specification code from literate specifications. We manually adapted specifications that did not adhere to the ISO standard.
Table 3 lists the suite of integration tests that we obtained in this way. The
table also shows the lines of code (excluding blank lines and comments) that each
test specification contains, as well as the rule coverage (RC) and non-terminal
coverage (NC) metrics for each. The coverage metrics shown were obtained with
the final, refactored grammar.
Note that in spite of the small size of the integration test suite in terms of
lines of code, the test coverage it offers for the grammar is satisfactory. Still, since
test coverage is not 100%, a follow-up project specifically aimed at enlarging the
integration test suite would be justified.
Unit tests During development, unit tests were created incrementally. For every
problem encountered, one or more unit tests were created to isolate the problem.
We measured unit tests development during grammar evolution in terms of
lines of unit test code, and coverage by unit tests in terms of rules (RC) and
non-terminals (NC). This development is shown graphically in Figure 8. As the
chart indicates, all unit tests were developed during the disambiguation phase,
i.e. between development versions 1 and 32. There is a small fluctuation in the
4
Table 3. Integration test suite. The second column gives the number of code lines.
The third and fourth columns gives coverage values for the final grammar.
Origin
Specification of the MAA standard (Graeme Parkin)
Abstract data types (Matthew Suderman and Rick Sutcliffe)
A crosswords assistant (Yves Ledru)
Modelling of Realms in (Peter Gorm Larsen)
Exercises formal methods course Univ. do Minho (Tiago Alves)
Total
LOC
269
1287
144
380
500
2580
RC
19%
37%
28%
26%
35%
50%
NC
30%
53%
43%
38%
48%
70%
70
60
50
40
LOC
RC
NC
30
20
10
0
1
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 45 46 47 48
Fig. 8. The evolution of unit tests during development. The x-axis represents the 48
development versions. The three release versions among these are 1, 32, and 48. The
left y-axis corresponds to lines of unit test code. Rule coverage (RC) and non-terminal
coverage (NC) are shown as well.
Related work
Malloy and Power have applied various software engineering techniques during
the development of a LALR parser for C# [2]. Their techniques include versioning, testing, and the grammar size, complexity, and some of the structure
metrics that we adopted ([15], see Table 2). For Malloy and Power, an important
measure of grammar quality is the number of conflicts. In our setting, ambiguities play a prominent role, rather than conflicts, due to the use of a generalized
LR parser generation technology. We use test coverage as an additional measure
of grammar quality. Also, we develop unit tests and we use them in addition to
Concluding remarks
With the detailed grammar engineering case study presented in this paper, we
have contributed to the grammar engineering body of knowledge in several ways.
5.1
Contributions
We showed how grammar testing, grammar metrics, and coverage analysis can
be combined in systematic grammar development process that can be characterised as a tool-based methodology for iterative grammar development. We
have motivated the use of these grammar engineering techniques from the larger
context of grammar-centered language tool development, and we have conveyed
our experiences in using them in a specific grammar development project. We
have demonstrated that this approach can help to make grammar development
a controlled process, rather than a resource-intensive and high-risk adventure.
The approach that we explained and illustrated combines several techniques,
such as version control, unit testing, metrics, and coverage analysis. We have
demonstrated how the development process can be monitored with various grammar metrics, and how tests can be used to guide the process of grammar disambiguation and refactorization. The presented metrics values quantify the size and
complexity of the grammar and reveal the level of continuity during evolution.
We have indicated how this case study extends earlier case studies [2, 3] where
some of these techniques were demonstrated before. Novelties in our approach
include the extensive use of unit tests, combined with monitoring of several
test coverage indicators. These unit tests document individual refactorings and
changes to resolve ambiguities.
As a side-effect of our case study, we have extended the collection of metric
reference data of [15] with values for several grammars of widely used languages,
and we have collected data for additional grammar metrics defined by us in [16].
Although we have used SDF as grammar formalism other formalisms such as
APIs, DSLs or DSMLs might benefit from similar approach. The methodology
can be used to guide the development. The importance of testing and tool support for testing is recognized in software engineering. Metrics can be used used
for validation, quality control, productivity and comparison.
5.2
Future work
L
ammel generalized the notion of rule coverage and advocates the uses of coverage analysis in grammar development [21]. When adopting a transformational
approach to grammar completion and correction, coverage analysis can be used
to improve grammar testing, and test set generation can be used to increase
coverage. SDF tool support for such test set generation and context-dependent
rule coverage analysis has yet to be developed.
We plan to extend the grammar in a modular way to cover other dialects
of the VDM-SL language, such as IFAD VDM and VDM++ . We have already
generated Haskell support for VDM processing for the grammar, and are planning to provide generate Java support as well. The integration test suite deserves
further extension in order to increase coverage.
Availability The final version of the ISO VDM-SL grammar in SDF (development version 48, release version 0.0.3) is available as browseable hyperdocument from http://voodoom.sourceforge.net/iso-vdm.html. All intermediate
versions can be obtained from the CVS repository at the project web site at
http://voodoom.sourceforge.net/, under an open source license. The SdfMetz
tool used for metrics computation is available from http://sdfmetz.googlecode.com.
References
1. Klint, P., L
ammel, R., Verhoef, C.: Towards an engineering discipline for grammarware. Transaction on Software Engineering and Methodology (2005) 331380
2. Malloy, B.A., Power, J.F., Waldron, J.T.: Applying software engineering techniques
to parser design: the development of a c# parser. In: In Proc. of the 2002 Conf. of
the South African Institute of Computer Scientists and Information Technologists,
pages 75 82, 2002. In cooperation with ACM, Press (2002) 7582
3. L
ammel, R., Verhoef, C.: Semi-automatic Grammar Recovery. SoftwarePractice
& Experience 31(15) (December 2001) 13951438
4. Brand, M.v.d., Sellink, A., Verhoef, C.: Current parsing techniques in software
renovation considered harmful. In: IWPC 98: Proceedings of the 6th International
Workshop on Program Comprehension, IEEE Computer Society (1998) 108117
5. Jonge, M.d., Visser, J.: Grammars as contracts. In: Proc. of the 2nd Int. Conference
on Generative and Component-based Software Engineering (GCSE 2000). Volume
2177 of Lecture Notes in Computer Science., Springer (2000) 8599
6. Heering, J., Hendriks, P.R.H., Klint, P., Rekers, J.: The syntax definition formalism
SDF Reference manual. SIGPLAN Notices 24(11) (1989) 4375
7. Visser, E.: Syntax Definition for Language Prototyping. PhD thesis, University of
Amsterdam (1997)
8. Brand, M.v.d., Deursen, A.v., Heering, J., Jonge, H.d., Jonge, M.d., Kuipers, T.,
Klint, P., Moonen, L., Olivier, P., Scheerder, J., Vinju, J., Visser, E., Visser, J.:
The ASF+SDF Meta-Environment: a component-based language development environment. In Wilhelm, R., ed.: Compiler Construction 2001 (CC 2001). Volume
2027 of LNCS., Springer-Verlag (2001)
9. Visser, E., Benaissa, Z.: A Core Language for Rewriting. In Kirchner, C., Kirchner, H., eds.: Proc. of the Int. Workshop on Rewriting Logic and its Applications
(WRLA98). Volume 15 of ENTCS., France, Elsevier Science (1998)
10. L
ammel, R., Visser, J.: A Strafunski Application Letter. In Dahl, V., Wadler, P.,
eds.: Proc. of Practical Aspects of Declarative Programming (PADL03). Volume
2562 of LNCS., Springer-Verlag (January 2003) 357375
11. Kuipers, T., Visser, J.: Object-oriented tree traversal with JJForester. In Brand,
M.v.d., Parigot, D., eds.: Electronic Notes in Theoretical Computer Science. Volume 44., Elsevier Science Publishers (2001) Proceedings of the Workshop on Language Descriptions, Tools and Applications (LDTA).
12. Jonge, M.d.: A pretty-printer for every occasion. In Ferguson, I., Gray, J., Scott, L.,
eds.: Proceedings of the 2nd International Symposium on Constructing Software
Engineering Tools (CoSET2000), University of Wollongong, Australia (2000)
13. Fogel, K.: Open Source Development with CVS. Coriolis Group Books (1999)
14. Kort, J., L
ammel, R., Verhoef, C.: The grammar deployment kit. In van den
Brand, M., L
ammel, R., eds.: ENTCS. Volume 65., Elsevier (2002)
15. Power, J., Malloy, B.: A metrics suite for grammar-based software. In: Journal of
Software Maintenance and Evolution. Volume 16., Wiley (November 2004) 405426
16. Alves, T., Visser, J.: Metrication of SDF grammars. Technical Report DI-PURe05.05.01, Universidade do Minho (May 2005)
17. Halstead, M.: Elements of Software Science. Volume 7 of Operating, and Programming Systems Series. Elsevier, New York, NY (1977)
18. Fenton, N., Pfleeger, S.L.: Software metrics: a rigorous and practical approach.
PWS Publishing Co., Boston, MA, USA (1997) 2nd edition, revised printing.
19. Bravenboer, M.:
Parse Unit home page http://www.programtransformation.org/Tools/ParseUnit.
20. Purdom, P.: Erratum: A Sentence Generator for Testing Parsers [BIT 12(3),
1972, p. 372]. BIT 12(4) (1972) 595595
21. L
ammel, R.: Grammar Testing. In: Proc. of Fundamental Approaches to Software
Engineering (FASE) 2001. Volume 2029 of LNCS., Springer-Verlag (2001) 201216
22. Alves, T., Silva, P., Visser, J., Oliveira, J.: Strategic term rewriting and its application to a VDM-SL to SQL conversion. In: Proceedings of the Formal Methods
Symposium (FM05), Springer (2005) 399414
23. International Organisation for Standardization:
Information technology
Programming languages, their environments and system software interfaces
Vienna Development MethodSpecification LanguagePart 1: Base language.
(December 1996) ISO/IEC 13817-1.
24. Brand, M.v.d., Scheerder, J., Vinju, J., Visser, E.: Disambiguation filters for
scannerless generalized LR parsers. In Horspool, N., ed.: Compiler Construction
(CC02). Volume 2304 of LNCS., France, Springer-Verlag (April 2002) 143158
25. L
ammel, R.: The Amsterdam toolkit for language archaeology (Extended Abstract). In: Proceedings of the 2nd International Workshop on Meta-Models,
Schemas and Grammars for Reverse Engineering (ATEM 2004). (October 2004)
26. Erbach, G.: Tools for grammar engineering (March 15 2000)
27. Volk, M.: The role of testing in grammar engineering. In: Proc. of the 3rd Conf.
on Applied Natural Language Processing, Assoc. for Computational Linguistics
(1992) 257258