1. Introduction
- Depot4 is a system for implementing language processors. Translators and interpreters are described by use of
the
Ml4
language (an extension of Extended Backus-Naur Form - EBNF - in the variant introduced
by Niklaus Wirth) and then processed into an executable program. In fact, Ml4 is translated into a host language,
which is widely hidden from
the user. Currently, Java is the host language of choice. (There was an implementation based on N. Wirth's
Oberon programming language, which has been maintained until version 1.8.)
Primarily, Depot4 is not intended to compete with the numerous compiler compilers. Instead we wanted to
build a tool for domain specific language implementors, who usually have only fragmentary knowledge
concerning compiling techniques.
However, this report assumes that you know already about context-free languages and how to represent them
using grammar productions (rules). I.e., you should be able to understand the formal description of some
programming language as used in common defining reports.
1.1. Acceptable languages
- Depot4 generates parsers that work using recursive descent, but in contrast to most of its
competitors, allows a certain degree of backtracking. Thus, although there must not be left recursive
productions grammars need not to be LL(1). - Of course, grammars, which are (close to) LL(1) allow
faster parsers. - Depot4 generated parsers use a sequential trial and error approach when searching
the appropriate branch of an alternative. There is no undo of semantic actions during backtracking. The
latter feature allows, in principle, an unbounded look-ahead.
Using recursive descent parsing has several advantages:
- fast parsing
- good error detection and recovery
- readable code in the host language - no tables (This makes it straightforward to modify the parser or
to debug it by use of a host language debugger.)
Depot4 does not know a static, monolithic parser. Instead, there is just a collection of rules. The
wanted parser is created dynamically by selecting one rule as root production. All the
additional parts are loaded by need. This simplifies the reuse of translators as well as debugging
and development, because subsets of rules can be applied or tested rather independently.
(We will use the terms rule and production as synonyms throughout this document.)
1.2. Runtime support
- Depot4 generated parsers as the Ml4 translator itself use a set of general support modules. Their
names start with "Dp4". (The upper case starting letter is left from Oberon implementation.) This modules can
be grouped into:
- general support functions
- modules for the creation of certain execution environments, e.g., message texts
- some plain symbol management:
Dp4List
- additional helper functions (date, time, splitting strings etc.):
Dp4Util
- an user interface
Writing language processors in Ml4 does not require detailed understanding of these modules in general.
Of course, this may differ if more elaborate techniques shall be implemented.
1.3. System flow
- When implementing language processors one has to be aware of two different things:
implementation and application. This is essential as both look rather similar and,
in fact, implementation is usually the application of the supplied language processor of the associated
meta-language. Therefore the Depot4 interface distinguishes two modes of operation. The translate
mode serves for implementing language processors, i.e., your meta-linguistic descriptions are processed to
produce the translator aimed for. In the use mode, generated language processors can be applied (or
even used) to process (parse, interpret, or translate) an arbitrary source text.
The steps involved in producing a new language processor for a language called slang
with
Depot4 are
- Define the syntax (and possibly its translation) of
slang
by use of Ml4.
- Process every rule with the Ml4 translator. This will create an adequate program text in the host
language (Java) and automatically call the respective compiler to produce a loadable output.
If your rule defines the nonterminal NT the generated files will be called
NT.java
and NT.class
.
You can prepare your rules with an ordinary text editor as well as enter them directly into the source
window of the user interface.
- To run your language processor switch from the translate into the use mode and
define the translator by selection of its root nonterminal, e.g.
slangRoot
. Then enter an
appropriate source text and start the translation. That's all.
The Depot4 runtime uses the dynamic loading facilities of the underlying host languages. There is no need
for an explicit link step. A further advantage is that you can run almost incomplete processors as long as
the yet not implemented rules are not really needed. (A call of a rule for which an implementation is not
available will produce an error message, but it behaves as if the application of this rule had failed.)