package bjc.rgens.newparser; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.StringReader; import java.util.Scanner; /** * Reads {@link RGrammar} from a input stream. * * @author student * */ public class RGrammarParser { /** * The exception thrown when something goes wrong while parsing a grammar. * * @author student * */ public static class GrammarException extends Exception { /* * Serialization ID. */ private static final long serialVersionUID = -7287427479316953668L; /** * Create a new grammar exception with the specified message. * * @param msg * The message for this exception. */ public GrammarException(String msg) { super(msg); } /** * Create a new grammar exception with the specified message and cause. * * @param msg * The message for this exception. * * @param cause * The cause of this exception. */ public GrammarException(String msg, Exception cause) { super(msg, cause); } } /** * Read a {@link RGrammar} from an input stream. * * @param is * The input stream to read from. * * @return The grammar represented by the stream. * * @throws GrammarException * Thrown if the grammar has a syntax error. */ public RGrammar readGrammar(InputStream is) throws GrammarException { LineNumberReader lnReader = new LineNumberReader(new InputStreamReader(is)); try (Scanner scn = new Scanner(lnReader)) { scn.useDelimiter("\\n\\.?\\n"); RGrammarBuilder build = new RGrammarBuilder(); while (scn.hasNext()) { String block = scn.next(); if (block.startsWith("pragma")) { handlePragmaBlock(block, build); } else if (block.startsWith("[")) { handleRuleBlock(block, build); } else { throw new GrammarException(String.format("Unknown block: %s", lnReader.getLineNumber(), block)); } } } catch (GrammarException gex) { throw new GrammarException(String.format("Error at line %d", lnReader.getLineNumber()), gex); } return null; } private void handlePragmaBlock(String block, RGrammarBuilder build) throws GrammarException { LineNumberReader lnReader = new LineNumberReader(new StringReader(block)); try (Scanner deblocker = new Scanner(lnReader)) { deblocker.useDelimiter("\\n(?!\\t)"); while (deblocker.hasNext()) { String pragma = deblocker.next(); if (!pragma.startsWith("pragma")) { throw new GrammarException(String.format("Illegal line at line %d of pragma block: %s", lnReader.getLineNumber(), pragma)); } } } } private void handleRuleBlock(String block, RGrammarBuilder build) { // TODO Auto-generated method stub } }