How to Read MinXML

To start with, we we simply read a MinXML expression off the console input and report whether or not it was syntactically well-formed. Create an initial package called anything you like (say com.steelypip.tutorial.exercises.minxml) and add a class in the source folder (src) called CheckInput. Add an empty starting method called main. You should have something like this:

package com.steelypip.tutorials.exercises.minxml;
 
public class CheckInput {
    public static void main( String[] args ) {
        // Code goes here.
    }
}

The MinXML parsers take their input from instances of java.io.Reader but the console input comes from System.in, which is a lower-level class called an InputStream. So the very first thing is to wrap it up into a java.io.Reader using new InputStreamReader(System.in).

package com.steelypip.tutorials.exercises.minxml;
 
import java.io.InputStreamReader;
import java.io.Reader;
 
public class CheckInput {
    public static void main( String[] args ) {
        final Reader input = new InputStreamReader( System.in );
        // The rest of the code goes here.
    }
}

At this point you can create an instance of a MinXMLParser, which will read expressions from the input or complain, using new MinXMLParser(input). You should read a single MinXML element off the input stream using the method readElement(). Both MinXML and MinXMLParser come from the package com.steelypip.powerups.minxml.

    public static void main( String[] args ) {
        final Reader input = new InputStreamReader( System.in );
        final MinXMLParser parser = new MinXMLParser( input );
        final MinXML m = parser.readElement();
        // Trap problems somehow.
    }

If the input is empty, then readElement will return null. That is because a very common use of MinXML is as the message format in a stream of messages. But if the input is malformed, then it will throw a java.lang.Exception. You can (and should) test this out. Add a little println to show the answer so far:

package com.steelypip.tutorials.exercises.minxml;
 
import java.io.InputStreamReader;
import java.io.Reader;
 
import com.steelypip.powerups.minxml.MinXML;
import com.steelypip.powerups.minxml.MinXMLParser;
 
public class CheckInput {
    public static void main( String[] args ) {
        final Reader input = new InputStreamReader( System.in );
        final MinXMLParser parser = new MinXMLParser( input );
        final MinXML element = parser.readElement();
        System.out.println( "" + element );
    }
}

Assuming you are using Eclipse, right click on the CheckInput class and pick Run As > Java Application. You may have to manually open the console window next, Window > Show View > Console. The console will be waiting for your input. Type Ctrl-d, a shortcut which signals end of input, and you should see the result null printed (and the run should finish). If you type a valid MinXML expression, such as <foo/>, then it should simply echo it back. But if you type an invalid expression, such as 99clunk, it will complain noisily. We will fix this up in a moment.

Exception in thread "main" ALERT : Unexpected character
WANTED   : <
RECEIVED : 9

    at com.steelypip.powerups.minxml.MinXMLParser.mustReadChar(MinXMLParser.java:70)
    at com.steelypip.powerups.minxml.MinXMLParser.read(MinXMLParser.java:238)
    at com.steelypip.powerups.minxml.MinXMLParser.readElement(MinXMLParser.java:281)
    at com.steelypip.tutorials.exercises.minxml.CheckInput.main(CheckInput.java:13)

So, now we know how the parser behaves, we want to report whether or not it liked the input. That's just a matter of checking for null and exceptions. Here's the finished code. Try it out.

package com.steelypip.tutorials.exercises.minxml;
 
import java.io.InputStreamReader;
import java.io.Reader;
 
import com.steelypip.powerups.minxml.MinXML;
import com.steelypip.powerups.minxml.MinXMLParser;
 
public class CheckInput {
    public static void main( String[] args ) {
        final Reader input = new InputStreamReader( System.in );
        final MinXMLParser parser = new MinXMLParser( input );
        try {
            final MinXML element = parser.readElement();
            if ( element == null ) {
                System.out.println( "Unexpected end of input" );
            } else {
                System.out.println( "Correctly formed MinXML" );
            }
        } catch ( Exception _ ) {
            System.out.println( "Malformed MinXML" );
        }
    }
}