inf.compilers
Interface SyntaxAdaptor<R extends SyntaxAdaptable>

Type Parameters:
R - the internal representation class
All Known Implementing Classes:
XmlAdaptor

public interface SyntaxAdaptor<R extends SyntaxAdaptable>

This interface represents an adaptor between an internal Java object that exists in memory and an external representation of this object as a sequence of characters. More specifically, the internal Java object must implement the SyntaxAdaptable interface. A SyntaxAdaptor provides functionality for writing a SyntaxAdaptable to a given Writer using the write(R, java.io.Writer) or prettyPrint(int, R, java.io.Writer) methods, and it provides functionality for creating such an object by parsing characters from a given Reader using the read(java.io.Reader) method. These are the most important functions performed by a SyntaxAdaptor.

A similar concept is implemented in the standard Java library, but only for the Date class as the internal representation. This class is called DateFormat. Using a DateFormat an internal object, a Date, can be transformed into a String according to a format specification, thus allowing for different syntaxes. Also, a DateFormat can take such a String and transform it into the Date that corresponds to the String. Thus, A DateFormat would be SyntaxAdaptor<Date> in our terminology.

The way in which a SyntaxAdaptor transforms an internal object into a sequence of characters and vice versa can be influenced by a set of properties. The currently used properties can be accessed and modified using the getProperty(java.lang.String) and setProperty(java.lang.String, java.lang.String) methods. No specific properties are defined at this level, only the mechanism to access them is generic.

The most important functions to implement are the methods for writing and reading. These functions define the syntax that is used for the external representation as a character sequence and an implementation of a SyntaxAdaptor should define, in its documentation, this syntax in BNF (or similar).

Finally, a SyntaxAdaptor can be tested using code similar to the following, where MySyntaxAdaptable is a class implementing SyntaxAdaptable and MySyntaxAdaptor implements SyntaxAdaptor<MySyntaxAdaptable>:

 SyntaxAdaptor<MySyntaxAdaptable> adaptor = new MySyntaxAdaptor();
 MySyntaxAdaptable original = new MySyntaxAdaptable(...);
 
 StringWriter w = new StringWriter();
 adaptor.prettyPrint(0, original, w);
 w.close();
 
 System.out.println(w.toString());
 
 StringReader r = new StringReader(w.toString()); 
 MySyntaxAdaptable copy = adaptor.read(r); 
 r.close();
 
 Writer sysout = new OutputStreamWriter(System.out);
 sa.prettyPrint(0, copy, sysout);
 sysout.flush();
 
 assert original.equals(copy);
 

This function first creates a SyntaxAdaptor adaptor and a SyntaxAdaptable object original for testing. The next three lines pretty-print the external format of original to the StringWriter w. This is then written to the standard output. Next, the external format is parsed to create another SyntaxAdaptable copy, which is again transform to its external format and pretty-printed a second time. The final assertion states that the two SyntaxAdaptables, original and copy, should be equal.

Author:
Gerhard Wickler

Method Summary
 java.lang.Class<R> getInternalClass()
           This function returns the Class that holds the internal representation this adaptor translates to and from.
 java.lang.String getProperty(java.lang.String key)
           This function gets the property that is associated with the given key.
 java.lang.String getSyntaxName()
           This function returns the name that should identify the syntactical language that this adaptor translates to and from.
 void prettyPrint(int indent, R intern, java.io.Writer w)
           This function takes a Java object in the internal representation (a SyntaxAdaptable), and writes it to the given Writer as a string conforming to the syntax of the language used by this adaptor.
 R read(java.io.Reader r)
           This function attempts to parse characters from the given Reader until a sentence that represents an object in the internal representation R has been parsed.
 void setProperty(java.lang.String key, java.lang.String value)
           This function sets the property associated with the given key to the given value.
 void write(R intern, java.io.Writer w)
           This function takes a Java object in the internal representation (a SyntaxAdaptable), and writes it to the given Writer as a string conforming to the syntax of the language used by this adaptor.
 

Method Detail

getInternalClass

java.lang.Class<R> getInternalClass()

This function returns the Class that holds the internal representation this adaptor translates to and from. This must be the same as the class parameter (R) taken by this SyntaxAdaptor.

Returns:
the internal representation Class adapted to

getSyntaxName

java.lang.String getSyntaxName()

This function returns the name that should identify the syntactical language that this adaptor translates to and from. Since this is a String, no constraints are enforced on its format. However, it would be a good idea if this was a URL pointing to a BNF definition of the syntax of this language.

Returns:
the name of the syntactical language adapted to

write

void write(R intern,
           java.io.Writer w)
           throws ExpressivenessException,
                  java.io.IOException

This function takes a Java object in the internal representation (a SyntaxAdaptable), and writes it to the given Writer as a string conforming to the syntax of the language used by this adaptor. No unnecessary space or newline characters are added to keep the output short.

Parameters:
intern - a SyntaxAdaptable in the internal representation R
w - the Writer to which the character sequence is written
Throws:
ExpressivenessException - if the syntactical language used cannot represent the complete given internal object
java.io.IOException - if writing to the given Writer fails

prettyPrint

void prettyPrint(int indent,
                 R intern,
                 java.io.Writer w)
                 throws ExpressivenessException,
                        java.io.IOException

This function takes a Java object in the internal representation (a SyntaxAdaptable), and writes it to the given Writer as a string conforming to the syntax of the language used by this adaptor. Space and formatting will be inserted to make the result more readable.

Parameters:
indent - the amount of indentation for the first line
intern - a SyntaxAdaptable in the internal representation R
w - the Writer to which the character sequence is written
Throws:
ExpressivenessException - if the syntactical language used cannot represent the complete given internal object
java.io.IOException - if writing to the given Writer fails

read

R read(java.io.Reader r)
                               throws ExpressivenessException,
                                      java.text.ParseException,
                                      java.io.IOException

This function attempts to parse characters from the given Reader until a sentence that represents an object in the internal representation R has been parsed.

Parameters:
r - the Reader from which the representation is to be parsed
Returns:
an object in the target internal representation R
Throws:
ExpressivenessException - if the internal representation class is not expressive enough to hold the object described by the character sequence taken from the Reader
java.text.ParseException - if there is a syntax error in the given character input taken from the Reader
java.io.IOException - if reading from the Reader fails

getProperty

java.lang.String getProperty(java.lang.String key)

This function gets the property that is associated with the given key. Note that the key should not be null.

Parameters:
key - the String that identifies the sought property value
Returns:
the property value for the given key (or null if undefined)

setProperty

void setProperty(java.lang.String key,
                 java.lang.String value)

This function sets the property associated with the given key to the given value. The given key must not be null, but the value may be.

Parameters:
key - the property name with which the value is associated
value - the associated value