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
ResourceReader()).getResourceReader("lexer.txt"));
GenParser.java, line 42: macros = new MacroExpander((new
ResourceReader()).getResourceReader("parser.txt"));
GenProds.java, line 29: macros = new MacroExpander((new
ResourceReader()).getResourceReader("productions.txt"));
GenTokens.java, line 27: macros = new MacroExpander((new
ResourceReader()).getResourceReader("tokens.txt"));
GenTools.java, line 32: macros = new MacroExpander((new
ResourceReader()).getResourceReader("tools.txt"));
GenUtils.java, line 26: macros = new MacroExpander((new
ResourceReader()).getResourceReader("utils.txt"));
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
executable:
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;
try
{
inputStream=getClass().getResourceAsStream(pResourceName);
//the following line forces an exception if the inputStream could not be
read.
//In absence of this line, inputStream would just be null and happily
continue.
if (inputStream == null) throw new IOException(pResourceName + "
not found");
return new InputStreamReader(inputStream);
}
catch(Exception e)
{
try
{
final URL url = new URL("core:/" + ResourceReader.class.getName()
+ "." + pResourceName);
return new
InputStreamReader(url.openConnection().getInputStream());
}
catch(Exception e2)
{
throw new RuntimeException("unable to open " +
ResourceReader.class.getName() + "." + pResourceName);
}
}
}
}