Skip to main content

Über dieses Buch

This book identifies, defines and illustrates the fundamental concepts and engineering techniques relevant to applications of software languages in software development. It presents software languages primarily from a software engineering perspective, i.e., it addresses how to parse, analyze, transform, generate, format, and otherwise process software artifacts in different software languages, as they appear in software development. To this end, it covers a wide range of software languages – most notably programming languages, domain-specific languages, modeling languages, exchange formats, and specifically also language definition languages. Further, different languages are leveraged to illustrate software language engineering concepts and techniques. The functional programming language Haskell dominates the book, while the mainstream programming languages Python and Java are additionally used for illustration.
By doing this, the book collects and organizes scattered knowledge from software language engineering, focusing on application areas such as software analysis (software reverse engineering), software transformation (software re-engineering), software composition (modularity), and domain-specific languages. It is designed as a textbook for independent study as well as for bachelor’s (advanced level) or master’s university courses in Computer Science. An additional website provides complementary material, for example, lecture slides and videos.
This book is a valuable resource for anyone wanting to understand the fundamental concepts and important engineering principles underlying software languages, allowing them to acquire much of the operational intelligence needed for dealing with software languages in software development practice. This is an important skill set for software engineers, as languages are increasingly permeating software development.



Chapter 1. The Notion of a Software Language

In this chapter, we characterize the notion of “software language” in a broad sense. We begin by setting out diverse examples of programming, modeling, and specification languages to cover a wide range of use cases of software languages in software engineering. Then, we classify software languages along multiple dimensions and describe the lifecycle of software languages, with phases such as language definition and implementation. Finally, we identify areas in software engineering that involve software languages in different ways, for example, software reverse engineering and software re-engineering.
Ralf Lämmel

Chapter 2. A Story of a Domain-Specific Language

In this chapter, several fundamental concepts and engineering techniques for software languages are explained by means of an illustrative domain-specific language. In particular, we exercise the internal and external styles of DSL implementation, textual and visual syntax, parsing, interpretation, and code generation. As a running example, we deal with a DSL for finite state machines FSML (FSM Language). In addition to implementing FSML with mainstream languages and technologies, we discuss design and implementation options and concerns overall and we describe a number of “recipes” for DSL development.
Ralf Lämmel

Chapter 3. Foundations of Tree- and Graph-Based Abstract Syntax

A software language can be regarded as a set of structured elements with some associated meaning. A language’s syntax defines its elements and their structure. We may speak of string, tree, and graph languages – to convey the nature of the elements’ structure. One may distinguish two forms of syntax: concrete versus abstract syntax. The former is tailored towards processing (reading, writing, editing) by humans who are language users; the latter is tailored towards processing (parsing, analyzing, transforming, generating) by programs that are authored by language implementers. In this chapter, we cover the foundations of abstract syntax. This includes the notion of conformance of terms (trees) or models (graphs) to signatures or metamodels. The proposed notations for signatures and metamodels correspond to proper software languages in themselves, giving rise to a metametalevel that we develop as well. We defer implementation aspects of abstract syntax, coverage of concrete syntax, and semantics of languages to later chapters.
Ralf Lämmel

Chapter 4. Representation of Object Programs in Metaprograms

This chapter discusses different representation options for abstract syntax in the context of implementing programming languages or language-based software components. This is an important foundation for metaprogramming. That is, we assume that one language – the metalanguage – is used for writing programs that analyze, manipulate, translate, generate, or otherwise consume or produce programs in another language – the object language. In this context, abstract syntax thus plays the role of defining the object-program representation in metaprograms. This chapter also discusses other implementation aspects of abstract syntax: conformance checking, serialization, and resolution (AST-to-ASG mapping).
Ralf Lämmel

Chapter 5. A Suite of Metaprogramming Scenarios

This chapter is a basic introduction to metaprogramming. A metaprogram is a program that processes (i.e., takes as input or produces as output) programs. Metaprogramming is at the heart of software language implementation and processing. The processed programs or artifacts are also referred to as object programs. The language in which the metaprograms are written is referred to as the metalanguage. The language of the processed programs or artifacts is referred to as the object language. The following are all important scenarios of metaprogramming: interpretation, compilation, transformation, analysis, and code generation. In this chapter, we exercise several metaprogramming scenarios using Haskell as the metalanguage.
Ralf Lämmel

Chapter 6. Foundations of Textual Concrete Syntax

In this chapter, we consider the notion of concrete syntax of software languages thereby complementing the earlier discussion of abstract syntax (Chapters 3and 4). Concrete syntax is tailored towards processing (reading, writing, editing) by humans who are language users, while abstract syntax is tailored towards processing by programs that are authored by language implementers. In this chapter, we focus on the concrete syntax of string languages as defined by context-free grammars (CFGs). In fact, we cover only textual concrete syntax; we do not cover visual concrete syntax. We introduce the algorithmic notion of acceptance for a membership test for a language.We also introduce the algorithmic notion of parsing for recovering the grammar-based structure of input. We defer the implementation aspects of concrete syntax, including actual parsing approaches, to the next chapter.
Ralf Lämmel

Chapter 7. Implementation of Textual Concrete Syntax

This chapter discusses implementation aspects of textual concrete syntax: parsing, abstraction, formatting, and the use of concrete as opposed to abstract object syntax in metaprograms. We focus on how parsers, formatters, etc. are actually implemented in practice, subject to using appropriate libraries, tools, and metaprogramming techniques.
Ralf Lämmel

Chapter 8. A Primer on Operational Semantics

The semantics of a software language assigns meanings to the elements of the language. The field of programming language theory provides rigorous techniques for the definition of semantics which are based on mathematical and logical tools. In this chapter, we introduce the method of operational semantics: inference rules are used to model the stepwise computation of a program. We do not go into the details of the underlying theoretical underpinnings, but the level of formality may help in developing and reasoning about interpreters and other semanticsaware language processing components (e.g., analyzers, optimizers, or refactorings) more systematically. We demonstrate the implementation of operational semantics in Haskell.
Ralf Lämmel

Chapter 9. A Primer on Type Systems

Types are semantic properties of program phrases. For instance, the type of an expression may model what type of value the expression would be evaluated to eventually, for example, the type of natural numbers or of Boolean values in an expression language. Types may be assigned to program phrases statically by means of a type system – this is a formal system consisting of inference rules, very much like a semantics definition. Assigned types (“properties”) must predict runtime behavior in a sound manner, i.e., the properties should never be violated by the actual runtime behavior. This is also referred to as type safety (or soundness). The rules making up a type system are easily implemented as type checkers, for example, in Haskell, as we will demonstrate. In this chapter, we provide a (very) basic introduction to type systems.
Ralf Lämmel

Chapter 10. An Excursion into the Lambda Calculus

The lambda calculus is an idealized programming language which captures the core of functional programming and serves as a notion of computability. The lambda calculus is also a good foundation for studying programming language concepts generally by means of adding dedicated extensions to the basic calculus. Our excursion into the lambda calculus is meant here to let us briefly visit a number of language concepts and aspects of semantics and typing that are of general interest in language design, definition, and implementation. This includes the notions of substitution, fixed-point computation, encoding, and type variance.
Ralf Lämmel

Chapter 11. An Ode to Compositionality

In this chapter, we complement the earlier development of operational semantics with another approach to defining semantics, namely the higher-order functional approach of denotational semantics. We focus here on compositionality, which is a structuring principle for interpreters, analyses, and yet other functionality for languages.We discuss two styles of denotational semantics: the simpler “direct” style and the more versatile “continuation” style capable of dealing with, for example, nonbasic control flow constructs. Denotational semantics can be implemented easily as interpreters, for example, in Haskell, as we will demonstrate.
Ralf Lämmel

Chapter 12. A Suite of Metaprogramming Techniques

Metaprogramming may be done with just a few programming techniques: an object-program representation (to capture the syntactical structure of object programs), pattern matching or accessors (to take apart object programs or to select suitable parts thereof), pattern building or constructors (to construct or compose object programs), and a computational model for tree walking (e.g., visitors in OO programming or possibly just recursion). In this chapter, we describe some metaprogramming techniques on the basis of which many metaprograms can be written in a more disciplined style. That is, we describe term rewriting, attribute grammars, multi-stage programming, partial evaluation, and abstract interpretation.
Ralf Lämmel


Weitere Informationen

Premium Partner

BranchenIndex Online

Die B2B-Firmensuche für Industrie und Wirtschaft: Kostenfrei in Firmenprofilen nach Lieferanten, Herstellern, Dienstleistern und Händlern recherchieren.



Best Practices für die Mitarbeiter-Partizipation in der Produktentwicklung

Unternehmen haben das Innovationspotenzial der eigenen Mitarbeiter auch außerhalb der F&E-Abteilung erkannt. Viele Initiativen zur Partizipation scheitern in der Praxis jedoch häufig. Lesen Sie hier  - basierend auf einer qualitativ-explorativen Expertenstudie - mehr über die wesentlichen Problemfelder der mitarbeiterzentrierten Produktentwicklung und profitieren Sie von konkreten Handlungsempfehlungen aus der Praxis.
Jetzt gratis downloaden!