Summary |  Admin |  Home Page |  Forums |  Tracker |  Bugs |  Support |  Patches |  Lists |  Tasks |  Docs |  Javadoc |  Surveys |  News |  CVS |  Files | 

org.jsesoft.jpp: A Java macro preprocessor


Title: A Java macro preprocessor.
Author: JSESoft
Company: JSESoft
Description: This is a simple preprocessor for Java (and other languages). It provides for macros and simple conditional compilation. Unicode is supported. The preprocessed code is written to a file which can be used as input for the Java compiler.

The implementation uses the sjm.parse.* packages by Steven John Metsker as described in his book "Building Parsers with Java" Addison Wesley 2001. This book comes with a CD containing the complete source code. This CD exposes the following readme:

This directory contains software and documentation associated with the book
"Building Parsers with Java," written by Steven John Metsker and published by
Addison-Wesley.

Copyright
---------
The code on the CD is free. It is copyrighted, so you may not claim that you
wrote the code. Otherwise you may use the code as you wish.

Disclaimer
----------
Neither the author nor the publisher warrants the code on this CD or in its
accompanying book to be free from defects. The author and publisher make no
representations or warranties about the fitness of this software for any
particular purpose, including the implied warranty of merchantability.

The preprocessor exposes the following weaknesses/features:

  • Java syntax isn't checked
  • Macro syntax differs somewhat from C (see grammar below)
  • Scientific notation for numbers not yet supported
  • Not yet tested extensively
  • Parsing is a little slow (due to sjm.parse)
  • Macro processing is done on tokens (rather than on characters)
  • No error recovery: preprocessor simply fails on invalid macro syntax)
A sample include file:
#ifndef TEST_INCL
#define TEST_INCL() #{#}

// --- file test.incl
#ifdef DEBUG
#define ENTER( name )
#{
        System.out.println("Enter " + name );
#}
#define LEAVE( name )
#{
        System.out.println("Leave " + name );
        return#}
#else
#define ENTER( name ) #{#}
#define LEAVE( name ) #{ return#}
#endif

#endif

A sample Java class:
// --- file MacroTest.java

#define DEBUG() #{#}
#include "test.incl"

class MacroTest
{

    #define MAX( a, b ) #{(a)>(b)?(a):(b)#}

    int max( int n1, int n2, int n3 )
    {
        #ENTER("max")
        // do something useful
        #LEAVE("max") #MAX(n1,#MAX(n2,n3));
    }
}

The result (DEBUG defined):
// --- file MacroTest.java





// --- file test.incl







class MacroTest
{



    int max( int n1, int n2, int n3 )
    {

        System.out.println("Enter " + "max" );

        // do something useful

        System.out.println("Leave " + "max" );
        return (n1)>((n2)>(n3)?(n2):(n3))?(n1):((n2)>(n3)?(n2):(n3));
    }
}

The result (DEBUG undefined):
// --- file MacroTest.java

// #define DEBUG() #{#}



// --- file test.incl







class MacroTest
{



    int max( int n1, int n2, int n3 )
    {

        // do something useful
         return (n1)>((n2)>(n3)?(n2):(n3))?(n1):((n2)>(n3)?(n2):(n3));
    }
}

The recognized grammar:

program = definition | macroCall | macroIfdef | macroIfndef | macroUndef
          macroElse | macroEndif | anyButMacros | macroInclude ;
macroIfdef = "#ifdef"  Identifier ;
macroIfndef = "#ifndef"  Identifier ;
macroUndef = "#undef"  Identifier ;
macroElse = "#else"  ;
macroEndif = "#endif"  ;
macroInclude = "#include" String ;
definition = "#define" blanks header blanks body ;
header = Identifier paramlist ;
paramlist = "(" ( params | Empty ) ")" ;
params = blanks Identifier ( blanks "," blanks Identifier )* ;
body = "#{" ( macroCall | anyButMacros )* "#}" ;
macroCall = "#" Identifier  arglist ;
arglist = "(" args | Empty ")" ;
args = blanks arg ( blanks "," blanks arg )* ;
arg = macroCall | anyButMacros ;
anyButMacros = anything but a # token ;
blanks = Whitespace;

Copyright: (c) 2002 JSESoft


Hosted by SourceForge Logo