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

compiling SableCc natively



-----------------
Proposed patches
-----------------

I have a SableCc-based application that contains two sets of
SableCc-generated lexers and parsers. In order to distinguish between the
files for each set of parsers to load from the core, the resource names
should be fully qualified. Otherwise, you can't have more than one generated
set in a single application; which is, on the contrary, perfectly possible
in the bytecode-version. Therefore, it should also be possible in the native
version.

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");

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);
		}
        }
    }
}