[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

sablecc with GCJ



Hi all

Since not everybody likes to deploy increasingly large JREs these days (30
Mb and more), I've compiled my SableCc-based project, datamodelartist, with
GCJ.

Now, everything works fine, except for one thing: the lexer and the parsers
don't find their lexer.dat and parser.dat file, since statements like --
Lexer.class.getResourceAsStream("lexer.dat") -- at line 61 of lexer.txt will
only work when the class was loaded from a jar or a foldertree of class
files.

Fortunately, people working on GCJ have been working hard, and Anthony Green
has added a protocol that permits loading resources from the executable's
body. A file "myresource.dat" can be stored in the GCJ-produced executable,
and retrieved as following:

      URL url = new URL("core:/myresource.dat");
	InputStream inputStream=url.openConnection ().getInputStream ()));

I've tried it, and it works perfectly well. There is only one loosely
related snag: ZipInputStream in libgcj is still bugged, and therefore, you
still can't store zip files (easily) in the executables. But then again, the
"core protocol" itself works fine.

In order to make the SableCc-generated lexer and parser work with the core
protocol, I have had to make minor changes to lexer.txt and parser.txt in
SableCc. These changes allow SableCc to load from the jar, if lexer.dat and
parser.dat can be found there, but before failing, it attempts to load them
"from the core". It really shouldn't affect the classical loading from the
jar or class files in any way. It would however, permit GCJ executables to
use SableCc generated logic, out of the box.

Is it possible to add these changes to SableCc?

Greetings
Erik Poupaert

---------------code-------------------------------------------

The changes to lexer.txt are:

import java.net.URL;


	      DataInputStream s=null;
		InputStream inputStream=null;
		try
		{
			inputStream=Lexer.class.getResourceAsStream("lexer.dat");
		}
		catch(Exception e)
		{
			inputStream=null;
		}
		if(inputStream==null)
		{
			URL url=new URL("core:/lexer.dat");
			s = new DataInputStream(
				    new BufferedInputStream(url.openConnection().getInputStream()));
		}
		else
		{
			s = new DataInputStream(
			    new BufferedInputStream(inputStream));
		}

And the changes to parser.txt are:

import java.net.URL;
import java.io.InputStream;

	      DataInputStream s=null;
		InputStream inputStream=null;
		try
		{
			inputStream=Parser.class.getResourceAsStream("parser.dat");
		}
		catch(Exception e)
		{
			inputStream=null;
		}
		if(inputStream==null)
		{
			URL url=new URL("core:/parser.dat");
			s = new DataInputStream(
				    new BufferedInputStream(url.openConnection().getInputStream()));
		}
		else
		{
			s = new DataInputStream(
			    new BufferedInputStream(inputStream));
		}