summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2016-05-08 19:03:09 +0200
committerPeter Wu <peter@lekensteyn.nl>2016-05-08 19:03:09 +0200
commit9f5a5c87bf7174620ef51605ffd6e93f828056ac (patch)
tree789761b38e83f1a195bb72faab6973c79105cb4f /src
parent35a991bdcc806e58627bc676341931aed0a71432 (diff)
downloadRegexTest-9f5a5c87bf7174620ef51605ffd6e93f828056ac.tar.gz
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.
Diffstat (limited to 'src')
-rw-r--r--src/PicoRec.java81
1 files 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();