previous         next         contents

Appendix D: Implementation specific issues

This appendix comprises implementation specific issues of the Depot4 system.
D1 Java
D1.1 Installation
D1.1.1 Java
D1.1.2 Depot4
D1.1.3 Running Depot4
D1.2 Metalanguage translation
D1.2.1 Packages
D1.2.2 Error location
D1.3 Extensions
D1.4 Library classes
D1.4.1 Dp4Util
D1.4.2 Dp4Tools
D1.4.3 Additional class terminals
D1.5 Configuration
D1.6 Implementation of external modules
D1.7 Logging interface

D1 Java

Originally, Depot4 was developed on base of Niklaus Wirth's Oberon system. When Java appeared on the scene it was soon realized an attractive migration target. The move was surprisingly fast and simple. For a while (until the 1.8.x versions), both implementations were kept fully source code compatible and maintained in parallel. This origin may explain some seeming singularities in naming and structure.
Depot4/Java was implemented first with JDK 1.0.2. The current version was tested against Java versions 1.4, 1.5, and 1.6. It is not expected that it will run with any pre-1.3 release.

D1.1 Installation

D1.1.1 Java

Depot4 expects a functional Java installation (Java Runtime Environment - JRE). This is not part of the Depot4 distribution. While a JRE is sufficient for running translators generated by Depot4 one needs a Java compiler (part of the Java Development Kit - JDK) for building them. So it is suggested to have a full JDK (or SDK resp.) installed on your machine.

Users who have already experience with Java software may skip the reminder of this section.

If you are unsure whether or not a Java Runtime Environment has been already installed at your computer, try to start or to find an application named 'java'. The command 'java -version' lets you know its actual version. If there is none, you can obtain your copy for free from http://java.com. There you will also find installation hints and sources for further support. Even if your type of platform is not directly supported by Sun, there is hope for finding a Java runtime in the web. (MacOS X is already shipped with its own implementation.)
Java has its own places where to search for resources, defined by the classpath. There are two ways to define the classpath. First, setting the CLASSPATH variable which is similar to any other path variable. Second, define the classpath in the command line, e.g.,

>java -classpath C:\j2sdk1.4.1\jre\lib\ext\tools.jar;C:\work\classes;. example.main
which has the advantage that it declines the risk of unintended interaction with other Java applications. At least, the classpath should contain all the jar archives from the directory ...\jre\lib\ and the application's archive and/or directory.

D1.1.2 Depot4

Depot4/Java is a rather compact software which could easily be shipped on a 1.4 MB floppy (including all sources). Installation is simple. The code is packed into one JAR archive. ( named Dp4Bxxx.jar, where xxx is the current version number.) Save it to an appropriate place (i.e. anywhere on your disk) and make it visible to the JVM by adding it (with full path) to the classpath. The complete classpath for running translators only may then look like:
   C:\work\Dp4B19.jar;C:\jdk\jre\lib\rt.jar;C:\jdk\jre\lib\i18n.jar

The different modes of use:

D1.1.3 Running Depot4

There are several ways of running Depot4. The remarks concerning the classpath hold for all of them. Failed attempts to start Depot4 are very likely due to missing classes and thus almost always due to missing or wrong entries in the classpath. Generated classes will be stored in the current directory. So be sure that it is in the classpath, too.
In principle, Depot4 can be run as an applet or a WebStart application, too. However, it makes no sense for building or changing translators because security restrictions may prevent access to the Java compiler and the generated source and class files. On the other hand, a generated translator is a very ordinary Java program which can be applied without any special restrictions.

Hint: To circumvent these restrictions, one can use the root production Ml4jT to generate the Java code from a Ml4 rule only. Save the generated code to a file and compile it elsewhere.

From the IDE
There are several ways of running Depot4, the most convenient one is from the shipped IDE. It allows you to construct translators, to apply, and to debug them.
In principle, the IDE can run as an applet or a WebStart application, too. Because of the already mentioned restrictions this makes sense for the application of translators only.

Swing based graphical user interface: ide
Java version: from 1.4.x
package name: Dp4.ide
main class: Dp4.ide.Main (extends java.applet.Applet)

The environment takes care that a newly translated module is applied subsequently. There is no need to restart.
One may add further locations where to search for modules to load in the Depot4.cfg file. Given the package name as in Java's package statement, e.g. "my.nice.pack" a rule "ThisRule" will be searched for as
  1. ThisRule
  2. This.ThisRule
  3. my.nice.pack.ThisRule
  4. Dp4.ThisRule
(If the name of the rule/module has no valid prefix as Thisrule, THISrule, etc. point 2 is skipped.)

To start the IDE enter the command line (check the classpath)

  java -classpath .;C:\work\Dp4B19.jar;...\tools.jar Dp4.ide.Main
Remark: The current directory '.' is the default place to start for (search and save) of generated translator rules.

The "Help" menu contains an item "Getting started" with further explanations.

Hint: A message There is no configuration file: Depot4.cfg is only an information indicating that the defaults are in use and not substituted.

From the command line
Running Depot4 from the command line is recommended for the application of generated translators only however, there is nothing (than inconvenience) preventing it for the implementation.
Source and target have to be files.
Example
Taking the example from 2.3.2 and assuming we have a nanoPascal program text stored in the file example.np and expect the result to be written into file example.c one can issue the command
  java -classpath .;C:\work\Dp4B19.jar....jre\lib\i18n.jar Dp4Run program example.np example.c
Any messages will be sent to the standard output stream. "nanoPascal2C" is the name of the translator's root production rule.
(The root name of the generator is "Ml4jTrans", requesting the compiler in the classpath. To see only the generated Java source use "Ml4jT".)
From within another Java application
As in all cases, one has to ensure that the Depot4 runtime (Dp4Bxxx.jar) and the path to the generated translator classes are in the classpath of the application.
The most simple (trivial) way to apply a Depot4 generated translator from within an application is to call the main method of the Dp4Run class (with the command line example):
  Dp4Run.main(new String[]{"nanoPascal2C", "example.np", "example.c"});
Another solution is to copy the appropriate code (the name "MyTranslator" has no specific meaning and will be used for logging purposes only):

// Create a Translator
Dp4.Translator translator= new Dp4.Translator("MyTranslator");  // may be static
// call translator:
Dp4.trgts tt= Dp4.Tools.translate(translator, Dp4.Files.IFile("example.np"), "nanoPascal2C");
if (Dp4.Tools.isOk(translator)) {
  // if successful write target on file
  Dp4.StreamTrg.Tar2Strm(tt.trg1, new Dp4.FileTrg("example.c"));
}
Remarks

D1.2 Metalanguage translation

D1.2.1 Packages

To allow a finer control of module/rule to Java package mapping, the translator supports a package directive. It overrides the default mapping approach.
Default mapping
Rule/module names which contain a non-empty prefix, i.e., there is a small letter or digit followed by a capital letter will be placed in package 'prefix'.
Example: AlfaBeta -> class AlfaBeta in package Alfa; alfa2BeTa -> class alfa2BeTa in package alfa2
Package directive
Placing (*!package=xx.yy.zz ...*) anywhere in the Ml4 code you can define a package name for the rule/module.
(*!nopackage ...*) disables the default package placement, i.e., the generated class is placed in the unnamed package (see Java Language Specification, 7.4.2).
Explicit package placing does by no means affect the default class search algorithm. See the Configuration section for how to make the classes reachable.

D1.2.2 Error location

Imported (foreign) modules are the main reason for Java compiling errors. As the metalanguage translator has no information it cannot do any checks and relies on their proper use. To make the back tracing of errors which are caused by improper method invocations simple, the generated Java code contains at each such call a comment with the associated Ml4 location.

Example
The Ml4 text
!BOOLEAN(Dp4Base.LogLevel.get(9))
in file C:\Ml4\Ml4jTrans.Ml4 is translated into
y_Prs.A=(Dp4.Base.LogLevel.get(9)/*$"C:\Ml4\Ml4jTrans.Ml4" pos 434 */);
An accidental type mismatch lets the Java compiler issue a log message like this, from which it is easy to locate the error at position 10 of the current input text area:
javac -d . -classpath .;C:\j...\classes tmp\src\a.java
tmp\src\a.java:29: appStr(Dp4.tNode,java.lang.String) in Dp4.Chars cannot be applied to (Dp4.tNode,int)
    y_0tg.trg1= Dp4.Chars.appStr(y_0tg.trg1, N/*$"" pos 10 */);

D1.3 Extensions

Depot4 generated translators can be extended in various respects very easily. Some simple examples are shipped with the distribution.
  1. Extensions which can be experienced from within the IDE via the Window>Add ...card menu:
    Dp4.ide.Counts
    Outputs simple statistics for every translation: counts the number of nonterminal invocations.
    Dp4.ide.Tree
    Outputs the syntax tree and its maximal depth with regard to the implemented grammar. For simplicity, the parent - child relation is pictured by indentation.
    Example
    The dummy Ml4 rule
    a= .
    produces with the Ml4 translator:
    Counts
    ------
    max. tree heigth:  5
    no. of nodes:  6
    ======================
    . Ml4jT
    . . Ml4jModule
    . . . Ml4jRule
    . . . . id
    . . . . Ml4jSrcExp
    . . . . . Ml4jSrcFact
    Also the trace, check, and debug functionality of the IDE are implemented by means of the nonterminal invocation extensibility.
  2. If a translator is used as part of a larger program it is useful sometimes to get an Abstract Syntax Tree (AST) of the processed source. The ASTBuilder extension provides this functionality. Its code may also serve as a guide for more sophisticated solutions.
    The ASTBuilder constructs the AST exploiting the nonterminal invocation extensibility. It appends an ASTDefaultNode to the AST for every successful nonterminal invocation. Modify the code for running Depot4 from within a Java application as follows:
      Dp4.Translator translator= new Dp4.Translator("MyTranslator");
      ASTBuilder astBuilder= new ASTBuilder();
    
      // initialize the ASTBuilder:
      astBuilder.clear();
      NTprocMonT.set(translator, astBuilder);
    
      // call translator:
      Dp4.trgts tt= Dp4.Tools.translate(translator, Dp4.Files.IFile("example.np"), "nanoPascal2C");
      if (Dp4.Tools.isOk(translator)) {
        // get the root of the AST:
        ASTNode rootNode= astBuilder.getASTRoot();
        // process it ...
      }
    
  3. The function of this extension is illustrated by two more classes which can be experienced from the IDE:
Extensions are part of the Dp4x package.

D1.4 Library classes

All library classes are part of the Dp4 package.

D1.4.1 Dp4Util

public static String Date()
Delivers the current date in standard format. The standard date format is specified by the Java runtime. It can be set explicitly in the system property "depot4.date.format".

D1.4.2 Dp4Tools

This module comprises some useful procedures that are used mainly by the interface.
public static trgts translate(Dp4.Translator t, Dp4.Source s, Dp4.NonTerm ROOT)
Translates the source s by use of the rules defined by ROOT and translation environment t.
public static trgts translate(Dp4.Translator t, Dp4.Source s, String ROOT)
Same as above, but the root is given as string.
public static trgts translate(Dp4.Source s, Dp4.NonTerm ROOT)
Translates the source s by use of the rules defined by ROOT. (Uses the default translation environment.)
public static trgts translate(Dp4.Source s, String ROOT)
Same as above, but the root is given as string.
public static boolean isOk(Dp4.Translator t)
Indicates the success of the translation (set by translate) in the translation environment t.
public static boolean isOk()
Indicates the success of the translation (set by translate in the default translation environment).
public static void setCap(boolean state)
If set true, capitalization in identifiers is significant.
public static boolean isCap()
Returns true if capitalization in identifiers is significant.

D1.4.3 Additional class terminals

There are some additional class terminals shipped with this release of Depot4.
identJava
Accepts identifiers excatly due to the definition of the Java language.
identPascal
Accepts identifiers consisting of letters and digits, whereby only the first 8 characters are significant. Capitalisation is insignificant. (These were the original rules of Pascal.)
identX
Accepts identifiers consisting of lettters, digits, and '_', starting with a letter. This class may serve as superclass for more specific implementations (such as the two above).
idForApplet
This is a specific implementation of ident which does not access the local file system and thus, cannot read an exclusion list from file. As the name tells it is intended for use in applets.

D1.5 Configuration

By default the system settings are such that no further configuration is required. However, there is a prearrangement to meet special needs. The most likely reason for configuring may be the wish to keep the Ml4 code clear of system specific notations. Some of the settings (e.g., all of them with regard to the Java compiler) make only sense for the building of translators.

There are three slots for the configuration of a Depot4 system:

  1. System properties
    This is the simplest way. One has to add the values for a number of predefined system properties in the command line.
    Example
      java -classpath .;C:....\tools.jar Dp4.ide.Main -DpropertyName1=value1 -DpropertyName2=value2
    
    Depot4 property names:
    depot4.work.dir
    Working directory for the generated source and class files. (Default value is the current user directory.)
    depot4.path
    The Depot4 classpath against which the Java compiler translates generated translator modules.
    depot4.java.compiler
    The name of a class implementing Dp4.HostCompiler, which is used as an internal compiler.
    depot4.compile.extern
    If the value is YES, the Java compiler is run as an own process. The JRE must be able to locate an executable called javac which accepts the same switches as Sun's Java compiler. Details for this may be system dependent.
    depot4.trans.packages
    A ';' separated list of package names. These may be needed if the translator contains modules for which the package was set explicitly by means of the package directive.
    depot4.date.format
    By this, one can change the default date format for the Ml4Date element. Possible formats are defined in java.text.DateFormat.
    Example
      java -classpath .;C:....jar Dp4.ide.Main -Ddepot4.work.dir=C:\work -Ddepot4.trans.packages=a.b.c;xx.y
    
  2. Configuration file
    A configuration file can contain four kinds of settings (letter case and sequence of settings are not significant):
    1. Switching case sensitivity
      cap=no /* insensitive */
      cap=yes /* sensitive - default */
    2. Overriding implementations, e.g.,
      local
      'id'<-'Dp4.idr'
      'ident'<-'Dp4.idr'
      
    3. Imported module name mappings, e.g.,
      map
      'Dp4OP'='Dp4.OP'
      'Other'='any.xxx.yyy.what'
      
    4. Package names for translator modules, e.g.,
      PACKAGE= 'xx.yy.zz'
      package ='a.b.c'
      
    Thus, a complete configuration file may look like:
    CAP=YES /* this is default */
    map
    'Dp4Streams'= 'Dp4.Streams'
    'Dp4DocFiles' = 'Dp4.DocFiles'
    'Dp4StrBuf'= 'Dp4.StrBuf'
    PACKAGE ='xx.yy.zz'
    package= 'a.b.c'
    
    The configuration file is searched for in the current user directory.
  3. Java source code
    Finally, a Depot4 installation can be configured by means of changing the class Dp4.config. This class is intended for costumization by modifying its method translatorCreated.
    By default it contains the paths for the standard class terminals and the code for reading the configuration file if any.

    Hint: Any of the classes can be substituted by creating a new class file and placing it in the classpath.

D1.6 Implementation of external modules

Because of the different modularization levels (modules vs. classes) in Ml4 and Java, the implementation of external modules needs some care. Static methods and types (classes) must be loacted in different classes. External type names must be implemented in a class called modulename_typename. Of course, module names can be mapped on any complete (i.e. including the full package name) class names.
Example
Ml4 text:
IMPORT External;
ExamplRule=
  VAR v1, v2: External.T1;
       v3: External.T2;
   ...
  External.M1(v1); ... v2:= External.T1("t"); ...
  v2.M3();
Java text:
public class External {
  public static void M1(External_T1 t) { ... }
  public static External_T1(String s) { ... }
}
public class External_T1 {
  public void M3() { ... }
}
public class External_T2 {... }
Type mappings of Ml4 types on Java types
INTEGER on int
BOOLEAN on boolean
REAL on float
SYM on java.lang.String
TXT on Dp4.tNode
TARGET on Dp4.trgts
The mapping of records, arrays and FLEX arrays is more difficult as specific access methods are generated. So it may be useful to define a nonterminal containing only the Ml4 type definitions and let the system generate the appropriate Java code. (Hint: One can use the translator by selecting "Ml4jT" as root.)
Mapping Java classes

ML4 assumes a module concept which distinguishes between modules and types or classes, i. e. a module is seen as a collection of types, each type determined by the pair modulename.typename. Java does not not know such a difference. So, if there is a need to declare variables of an external type (class), this class must be split into two parts: a class with the module name and another interface with name modulename_typename.
As an example the type Dp4List.List is translated into Dp4.List_List, while a call Dp4List.New(x) will result in Dp4.List.New(x);. There is no need to use the same name for both parts, cf. Dp4Streams.Stream.

Reminder: Of course, the location of the external (imported) classes must be reachable from the current working directory. Otherwise one has to append it to the classpath.

D1.7 Logging interface

Class Dp4LogStub implements a generic wrapper for logging with these methods:

public static LogStub getLog(String name)
Convenience method to return a named logger, without the application having to care about factories.
public boolean isLogEnabled(int severity)
Returns whether logging of severity is enabled for this LogStub.
public void log(int severity, String msg)
Writes the message into the log, if logging is enabled for severity.
public void log(int severity, String msg, Throwable ex)
Writes the message and exception stack into the log, if logging is enabled for severity.

Severity is an integer number, assuming 0 a default level, lesser values indicating more detailed logging.

This implementation offers an interface to Apache's Commons Logging. During initialization Depot4 looks for the class org.apache.commons.logging.LogFactory. If it is found, it is instantiated and all logging actions are delegated to it. Severities are mapped as follows:

      <-1: trace
       -1: debug
        0: info
        1: warn
        2: error
       >2: fatal

This logging interface is intended for extensions primarily. Currently, several classes of Depot4's runtime system use it, thus supporting the tracing facilities of the parser.


    previous         next         contents


© J. Lampe 1997-2010