From 9f5a5c87bf7174620ef51605ffd6e93f828056ac Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 8 May 2016 19:03:09 +0200 Subject: PicoRec: fully implemented Removed the LAYOUT matching from tokenRegex, these are not part of the token and should be removed before. Add an auxilliary function that tests whether a token that matches ID really is a non-keyword. Implement remaining expressions. --- src/PicoRec.java | 81 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 14 deletions(-) diff --git a/src/PicoRec.java b/src/PicoRec.java index 1d6e16b..d38297f 100644 --- a/src/PicoRec.java +++ b/src/PicoRec.java @@ -11,10 +11,9 @@ public class PicoRec { /** Regular expression describing the NAT symbol. */ private final static String natRegex = "0|[1-9][0-9]*"; - /** Regular expression matches all tokens accepted by the language (other - * than keywords). */ + /** Regular expression matches all tokens accepted by the language. */ private final static String tokenRegex = - literalRegex("[\\|,;\\+\\*\\-]|:=|" + idRegex + "|" + natRegex); + "[\\|,;\\+\\*\\-]|:=|" + idRegex + "|" + natRegex; /** Regular expression matching layout tokens (to be ignored). */ private final static String layoutRegex = "[ \n]*"; @@ -28,12 +27,6 @@ public class PicoRec { private String input; private int offset; - /** Auxilliary function to produce a regular expression taking into account - * layout considerations for symbols. */ - private static String literalRegex(String regex) { - return layoutRegex + "(" + regex + ")" + layoutRegex; - } - public PicoRec() { idR = new RunAutomaton(new RegExp(idRegex).toAutomaton()); natR = new RunAutomaton(new RegExp(natRegex).toAutomaton()); @@ -58,9 +51,17 @@ public class PicoRec { match(END_SYMBOL); } + /** Returns true if the next token is a non-keyword identifier. */ + private boolean isId(String token) { + boolean result = !("begin".equals(token) || "declare".equals(token) || + "end".equals(token)) && idR.run(token); + //System.err.println("Testing for ID: " + token + ": " + result); + return result; + } + private void parseIdList() { // Parses IDLIST ::= ID "," | - while (idR.run(next())) { + while (isId(next())) { match(next()); // ID match(","); } @@ -68,17 +69,68 @@ public class PicoRec { private void parseStatements() { // Parses STATEMENTS ::= STATEMENT ";" | - // => STATEMENT ::= ID ":=" EXP ";" | - while (idR.run(next())) { + // => STATEMENTS ::= ID ":=" EXP ";" | + while (isId(next())) { match(next()); // ID match(":="); parseExp(); - match(","); + match(";"); } } private void parseExp() { - // TODO implement me + // Parses EXP ::= PROD-EXP PLUS-EXP' + parseProdExp(); + parsePlusExpPrefixed(); + } + + private void parsePlusExp() { + // Parses PLUS-EXP ::= PROD-EXP PLUS-EXP' + parseProdExp(); + parsePlusExpPrefixed(); + } + + private void parsePlusExpPrefixed() { + // Parses PLUS-EXP' ::= "+" PROD-EXP PLUS-EXP' | + while ("+".equals(next())) { + match("*"); + parseProdExp(); + parsePlusExpPrefixed(); + } + } + + private void parseProdExp() { + // Parses PROD-EXP ::= SINGLE-EXP PROD-EXP' + parseSingleExp(); + parseProdExpPrefixed(); + } + + private void parseProdExpPrefixed() { + // Parses PROD-EXP' ::= "*" SINGLE-EXP PROD-EXP' | + while ("*".equals(next())) { + match("*"); + parseSingleExp(); + parseProdExpPrefixed(); + } + } + + private void parseSingleExp() { + // Parses SINGLE-EXP ::= "-" SINGLE-EXP | ID | NAT | "(" EXP ")" + String token = next(); + if ("-".equals(token)) { + match("-"); + parseSingleExp(); + } else if (isId(token)) { + match(token); + } else if (natR.run(token)) { + match(token); + } else if ("(".equals(token)) { + match("("); + parseExp(); + match(")"); + } else { + throw new ParseError("Invalid expression"); + } } /** Skip layout characters. */ @@ -123,6 +175,7 @@ public class PicoRec { } } else { if (!input.startsWith(symbol, offset)) { + //System.err.println("Current input: " + input.substring(offset)); throw new ParseError("Cannot match symbol: " + symbol); } offset += symbol.length(); -- cgit v1.2.1