From 22237d1476f1496aef6bebf066ff2e6652ba4953 Mon Sep 17 00:00:00 2001 From: bjculkin Date: Sat, 18 Mar 2017 20:01:27 -0400 Subject: More work on new parser --- .../main/java/bjc/rgens/newparser/RGrammar.java | 6 + .../java/bjc/rgens/newparser/RGrammarBuilder.java | 25 ++++ .../java/bjc/rgens/newparser/RGrammarParser.java | 151 ++++++++++++++++----- 3 files changed, 147 insertions(+), 35 deletions(-) (limited to 'RGens/src/main/java') diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java index 9b47bd6..64385e9 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammar.java @@ -1,5 +1,11 @@ package bjc.rgens.newparser; +/** + * Represents a randomized grammar. + * + * @author EVE + * + */ public class RGrammar { } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java index 3b48a2a..073e0ee 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarBuilder.java @@ -1,7 +1,32 @@ package bjc.rgens.newparser; +/** + * Construct randomized grammars piece by piece. + * + * @author EVE + * + */ public class RGrammarBuilder { + /** + * Sets the rule currently being built. + * + * @param rName The name of the rule currently being built. + */ + public void setCurrentRule(String rName) { + /* + * TODO implement. + */ + } + + /** + * Convert this builder into a grammar. + * + * @return The grammar built by this builder + */ public RGrammar toRGrammar() { + /* + * TODO implement. + */ return null; } } diff --git a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java index e31bb03..cf85cb5 100644 --- a/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java +++ b/RGens/src/main/java/bjc/rgens/newparser/RGrammarParser.java @@ -1,9 +1,13 @@ package bjc.rgens.newparser; +import bjc.utils.funcutils.TriConsumer; + import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; import java.util.Scanner; /** @@ -14,7 +18,8 @@ import java.util.Scanner; */ public class RGrammarParser { /** - * The exception thrown when something goes wrong while parsing a grammar. + * The exception thrown when something goes wrong while parsing a + * grammar. * * @author student * @@ -29,103 +34,179 @@ public class RGrammarParser { * Create a new grammar exception with the specified message. * * @param msg - * The message for this exception. + * The message for this exception. */ public GrammarException(String msg) { super(msg); } /** - * Create a new grammar exception with the specified message and cause. + * Create a new grammar exception with the specified message and + * cause. * * @param msg - * The message for this exception. + * The message for this exception. * * @param cause - * The cause of this exception. + * The cause of this exception. */ public GrammarException(String msg, Exception cause) { super(msg, cause); } } + /* + * Pragma impls. + */ + private static Map> pragmas; + + /* + * Initialize pragmas. + */ + static { + pragmas = new HashMap<>(); + } + /** * Read a {@link RGrammar} from an input stream. * * @param is - * The input stream to read from. + * The input stream to read from. * * @return The grammar represented by the stream. * * @throws GrammarException - * Thrown if the grammar has a syntax error. + * Thrown if the grammar has a syntax error. */ public RGrammar readGrammar(InputStream is) throws GrammarException { LineNumberReader lnReader = new LineNumberReader(new InputStreamReader(is)); int blockNo = 0; - try (Scanner scn = new Scanner(lnReader)) { + try(Scanner scn = new Scanner(lnReader)) { scn.useDelimiter("\\n\\.?\\n"); RGrammarBuilder build = new RGrammarBuilder(); - while (scn.hasNext()) { + while(scn.hasNext()) { String block = scn.next(); blockNo += 1; - 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)); - } + handleBlock(build, block, 0); } - } catch (GrammarException gex) { - throw new GrammarException(String.format("Error in block %d at line %d of stream", blockNo, lnReader.getLineNumber()), gex); + + return build.toRGrammar(); + } catch(GrammarException gex) { + throw new GrammarException(String.format("Error in block %d at line %d of stream", blockNo, + lnReader.getLineNumber()), gex); } + } + + /* + * Throughout these, level indicates the nesting level of that + * construct. + */ - return null; + /* + * Handles an arbitrary block. + */ + private void handleBlock(RGrammarBuilder build, String block, int level) throws GrammarException { + if(block.startsWith("pragma")) { + handlePragmaBlock(block, build, level); + } else if(block.startsWith("[")) { + handleRuleBlock(block, build, level); + } else if(block.startsWith("where")) { + handleWhereBlock(block, build, level); + } else { + throw new GrammarException(String.format("Unknown block: %s", block)); + } } /* - * Handle reading a block of pragmas + * Handle reading a block of pragmas. */ - private void handlePragmaBlock(String block, RGrammarBuilder build) throws GrammarException { + private void handlePragmaBlock(String block, RGrammarBuilder build, int level) throws GrammarException { LineNumberReader lnReader = new LineNumberReader(new StringReader(block)); int pragmaNo = 0; - try (Scanner deblocker = new Scanner(lnReader)) { - deblocker.useDelimiter("\\n(?!\\t)"); + try(Scanner deblocker = new Scanner(lnReader)) { + deblocker.useDelimiter(String.format("\\n\\t{%d}(?!\\t)", level)); - while (deblocker.hasNext()) { + while(deblocker.hasNext()) { String pragma = deblocker.next(); pragmaNo += 1; - if (!pragma.startsWith("pragma")) { - throw new GrammarException(String.format("Illegal line: %s", - lnReader.getLineNumber(), pragma)); + if(!pragma.startsWith("pragma")) { + throw new GrammarException(String.format("Illegal line: %s", pragma)); } else { - handlePragma(pragma.substring(7), build); + handlePragma(pragma.substring(7), build, level); } } - } catch (GrammarException gex) { - throw new GrammarException(String.format("Error in pragma %d at line %d", pragmaNo, lnReader.getLineNumber()), gex); + } catch(GrammarException gex) { + throw new GrammarException(String.format("Error in pragma %d at line %d", pragmaNo, + lnReader.getLineNumber()), gex); } } - private void handlePragma(String pragma, RGrammarBuilder build) { - + private void handlePragma(String pragma, RGrammarBuilder build, int level) throws GrammarException { + String pragmaName = pragma.substring(0, pragma.indexOf(' ')); + + if(pragmas.containsKey(pragmaName)) { + pragmas.get(pragmaName).accept(pragma.substring(pragma.indexOf(' ')), build, level); + } else { + throw new GrammarException(String.format("Unknown pragma %s", pragmaName)); + } } /* - * Handle a block of rules. + * Handle a block of a rule and multiple cases. */ - private void handleRuleBlock(String block, RGrammarBuilder build) { + private void handleRuleBlock(String block, RGrammarBuilder build, int level) throws GrammarException { LineNumberReader lnReader = new LineNumberReader(new StringReader(block)); + int caseNo = 0; try(Scanner scn = new Scanner(lnReader)) { - + scn.useDelimiter(String.format("\\n\\t\\t{%d}", level)); + + String decl = scn.next(); + + String ruleName = decl.substring(0, decl.indexOf(' ')); + + if(ruleName.equals("")) { + throw new GrammarException("The empty string is not a valid rule name"); + } + + build.setCurrentRule(ruleName); + + String initCase = decl.substring(decl.indexOf(' ')); + caseNo += 1; + + handleRuleCase(initCase, build); + + while(scn.hasNext()) { + String cse = scn.next(); + caseNo += 1; + + handleRuleCase(cse, build); + } + } catch(GrammarException gex) { + throw new GrammarException( + String.format("Error in case %d at line %d", caseNo, lnReader.getLineNumber()), + gex); } } + + /* + * Handle a single case of a rule. + */ + private void handleRuleCase(String initCase, RGrammarBuilder build) { + // TODO Auto-generated method stub + + } + + /* + * Handle a block of a rule with local rules. + */ + private void handleWhereBlock(String block, RGrammarBuilder build, int level) { + // TODO Auto-generated method stub + } } -- cgit v1.2.3