Extreme Parsing
by Kyle F. Downey

Example 1:
(a)
<interface> ::= <interface_dcl>
          |     <forward_dcl>


(b)
interface = {full_interface_declaration} interface_dcl 
       |    {forward_declaration} forward_dcl;

Example 2:

module M {
  interface thing {
    attribute boolean abstract; // error: abstract collides 
                                //  with keyword abstract
  };
};


Example 3:

Package com.amberarcher.corba.idl;
Helpers
  all = [0 .. 0xFFFF];
  lowercase = ['a' .. 'z'];
  uppercase = ['A' .. 'Z'];
  digit = ['0' .. '9'];

  tab = 9;
  cr = 13;
  lf = 10;
  eol = cr lf | cr | lf;

Example 4:

identifier_prefix = lowercase | uppercase ;
identifier_char =  identifier_prefix | digit | '_';

not_eol = [all - [cr + lf]];
not_star = [not_eol - '*'] | eol;
not_star_not_slash = [not_eol - ['*' + '/']] | eol;


Example 5:

Tokens
    interface = 'interface';
    identifier = identifier_prefix identifier_char*;
    white_space = (' ' | tab | eol)+;
    start_scope = '{';
    end_scope = '}';
    end_decl = ';';

Example 6:

Productions
    specification = definition+;
    definition = P.interface;
       interface = interface_dcl;
    interface_dcl =
        T.interface start_scope end_scope end_decl;


Listing One

<?xml version="1.0"?>
<project name="comc" default="compile" basedir=".">
    <!-- allow for local override of site settings -->
    <property file="${user.home}/.ant.properties"/>
    <property name="build.dir" value="${basedir}/build"/>
    <property name="build.classes.dir" value="${build.dir}/classes"/>
    <property name="build.gen-src.dir" value="${build.dir}/gen-src"/>
    <property name="src.dir" value="src/share/classes"/>
    <property name="grammar.dir" value="src/share/grammars"/>

    <path id="build_classpath">
        <pathelement path="${basedir}/lib/junit.jar"/>
    </path>

    <path id="tools_classpath">
        <pathelement path="${basedir}/build-tools/sablecc-anttask.jar"/>
        <pathelement path="${basedir}/build-tools/sablecc.jar"/>
    </path>

    <taskdef name="sablecc" classname="org.sablecc.ant.taskdef.Sablecc"
        classpathref="tools_classpath"/>
    <target name="generate_idl_parser">
        <mkdir dir="${build.classes.dir}"/>
        <mkdir dir="${build.gen-src.dir}"/>
        <sablecc src="${grammar.dir}" includes="idl.sablecc" 
                 outputdirectory="${build.gen-src.dir}"/> 
        <javac srcdir="${build.gen-src.dir}"
            destdir="${build.classes.dir}">
            <include name="**/*.java"/>
        </javac>
        <copy todir="${build.classes.dir}">
            <fileset dir="${build.gen-src.dir}">
                <include name="**/lexer.dat" />
                <include name="**/parser.dat" />
            </fileset>
        </copy>
    </target>
    <target name="compile">
        <mkdir dir="${build.classes.dir}"/>
        <javac srcdir="${src.dir}" classpathref="build_classpath"
            destdir="${build.classes.dir}">
            <include name="**/*.java"/>
        </javac>
        <copy todir="${build.classes.dir}">
            <fileset dir="${build.gen-src.dir}">
                <include name="**/lexer.dat" />
                <include name="**/parser.dat" />
            </fileset>
        </copy>
    </target>
    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>
</project>


Listing Two
package com.amberarcher.corba.idl.testing;
import java.io.FileReader;
import java.io.PushbackReader;
import java.io.File;
import junit.framework.TestCase;
import com.amberarcher.corba.idl.node.Start;
import com.amberarcher.corba.idl.parser.Parser;
import com.amberarcher.corba.idl.lexer.Lexer;

public class AbstractTestCase extends TestCase {
    public AbstractTestCase(String methodName) {
        super(methodName);
    }
    protected Start parse(String testCaseFileBaseName) throws Exception {
        FileReader fin = new FileReader("src" + File.separator +
                "share" + File.separator + "test-fixtures" + 
                File.separator + "idl" +
                File.separator + testCaseFileBaseName);
        PushbackReader in = new PushbackReader(fin);
        Parser p = new Parser(new Lexer(in));
        return p.parse();
    }
}


Listing Three
public class StandardIdlParsingUnitTests extends AbstractTestCase {
    public StandardIdlParsingUnitTests(String methodName) {
        super(methodName);
    }
    public void testUnescapedIdentifierFails() throws Exception {
        String msg = null;
        boolean failed = false;
        try {
            parse("example-3.2.3.1-esc-identifiers-1.idl");
        } catch (ParserException e) {
            msg = e.getMessage();
            failed = true;
        }
        assertTrue(failed);
        assertEquals("[3,27] expecting: identifier, escaped identifier", msg);
    }
}


Listing Four
module M {
    interface base;              /* forward declaration */
    interface base { };
    interface thing : base {
        attribute boolean foo;   // creates get_foo(), set_foo()
    };
};


Listing Five
Package com.amberarcher.corba.idl;
Helpers
    all = [0 .. 0xFFFF];
    lowercase = ['a' .. 'z'];
    uppercase = ['A' .. 'Z'];
    digit = ['0' .. '9'];

    tab = 9;
    cr = 13;
    lf = 10;
    eol = cr lf | cr | lf;

    identifier_prefix = lowercase | uppercase ;
    identifier_char =  identifier_prefix | digit | '_';
    not_eol = [all - [cr + lf]];
    not_star = [not_eol - '*'] | eol;
    not_star_not_slash = [not_eol - ['*' + '/']] | eol;

Tokens
    // different types of comments
    traditional_comment = '/*' not_star+ '*'+ 
           (not_star_not_slash not_star* '*'+)* '/';
    end_of_line_comment = '//' not_eol* eol?;
    attribute = 'attribute';
    boolean = 'boolean';
    interface = 'interface';
    module = 'module';
    identifier = identifier_prefix identifier_char*;
    white_space = (' ' | tab | eol)+;
    start_scope = '{';
    end_scope = '}';
    end_decl = ';';
    inherit_op = ':';
    interface_sep = ',';

Ignored Tokens
    white_space,
    traditional_comment,
    end_of_line_comment;

Productions
    specification = definition+;
    definition = P.interface;
    module = T.module T.identifier start_scope definition+  
             end_scope end_decl;
    interface = {interface_dcl} interface_dcl |
        {forward_dcl} forward_dcl;
    interface_dcl =
        interface_header start_scope interface_body end_scope end_decl;
    forward_dcl = interface_type? T.interface T.identifier end_decl;
    interface_header = 
        interface_type? T.interface T.identifier interface_inheritance_spec?;
    interface_type = {abstract} abstract |
        {local} local;
    interface_body = exports*;
    interface_inheritance_spec = 
        inherit_op interface_name interface_inheritance_spec_tail*;
    interface_inheritance_spec_tail = interface_sep interface_name;
    interface_name = scoped_name;

    exports = attr_dcl;
    attr_dcl = attribute type_declaration T.identifier end_decl;
    type_declaration = boolean;





5


