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

Re: compiling SableCc natively

Anybody, any objections to this?

My own comments follow....

The changes should be:

lexer.txt, line 106 should become: final URL url = new URL("core:/" +
Lexer.class.getName() + ".lexer.dat");
parser.txt, line 90 should become: final URL url = new URL("core:/" +
Parser.class.getName() + ".parser.dat");
Are you sure it should be:
Parser.class.getName() + ".pareser.dat" ? It will produce something like:

I think it should be: Parser.class.getPackage().getName() + ".pareser.dat", which will produce something like this:

By the way, the changes I had to make to SableCc, so that SableCc could be
compiled natively, are rather small as well:

GenLexer.java, line 30: macros = new MacroExpander((new
GenParser.java, line 42: macros = new MacroExpander((new
GenProds.java, line 29:  macros = new MacroExpander((new
GenTokens.java, line 27: macros = new MacroExpander((new
GenTools.java, line 32:  macros = new MacroExpander((new
GenUtils.java, line 26:  macros = new MacroExpander((new

ResourceReader centralizes the logic for reading resources. Therefore,
ResourceReader goes through the usual rigmarole, which consists in trying to
read from the jar-file first. If it fails, it tries to read from the core;
by the way, failing to read from the core throws an exception unlike failing
to read from the jar-file. I've made sure to fully qualify the resource to
read, so that multiple lexers and parsers can participate in the same

package org.sablecc.sablecc;

import java.io.*;
import java.net.URL;

//contributed by Erik Poupaert, in order to compile sablecc natively.

public class ResourceReader
	public Reader getResourceReader(String pResourceName)
		InputStream inputStream=null;
				//the following line forces an exception if the inputStream could not be
				//In absence of this line, inputStream would just be null and happily
		       if (inputStream == null) throw new IOException(pResourceName + "
not found");
		       return new InputStreamReader(inputStream);
		catch(Exception e)
			      final URL url = new URL("core:/" +  ResourceReader.class.getName()
+ "." + pResourceName);
			      return new
		catch(Exception e2)
		    throw new RuntimeException("unable to open " +
ResourceReader.class.getName() + "." + pResourceName);

I suggest renaming this class to ResourceHelper (or similar) just not to make confusion with the Reader interface -- as you pointed out this class does not make a full Reader contract anyway.
I also suggest making it final, because it is being used internally by sablecc, and all modifications will not be done by inheritance anyway. And I suggest making the method final static, so we do not need to instantiate ResourceHelper everytime we load a resource. So we would have something like this:

macros = new MacroExpander(ResourceHelper.getReader("lexer.txt"));

instead of this:
macros = new MacroExpander((new ResourceReader()).getResourceReader("lexer.txt"));

Again, are you sure it should be:
final URL url = new URL("core:/" + ResourceReader.class.getName() + "." + pResourceName);

and not:

final URL url = new URL("core:/" + ResourceReader.class.getPackage().getName() + "." + pResourceName);


I am asking that because I do not really know the mechanisms for loading resources in GCJ and it just looks strange with this "L" in front ;o)