summaryrefslogtreecommitdiff
path: root/chapter01
diff options
context:
space:
mode:
Diffstat (limited to 'chapter01')
-rw-r--r--chapter01/src/main/java/com/seaofnodes/simple/Parser.java43
-rw-r--r--chapter01/src/main/java/com/seaofnodes/simple/node/Node.java1
-rw-r--r--chapter01/src/test/java/com/seaofnodes/simple/ParserTest.java19
3 files changed, 30 insertions, 33 deletions
diff --git a/chapter01/src/main/java/com/seaofnodes/simple/Parser.java b/chapter01/src/main/java/com/seaofnodes/simple/Parser.java
index e9cae52f..a4c07217 100644
--- a/chapter01/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter01/src/main/java/com/seaofnodes/simple/Parser.java
@@ -1,9 +1,9 @@
package com.seaofnodes.simple;
-import com.seaofnodes.simple.node.*;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
+import com.seaofnodes.simple.node.ConstantNode;
+import com.seaofnodes.simple.node.Node;
+import com.seaofnodes.simple.node.ReturnNode;
+import com.seaofnodes.simple.node.StartNode;
/**
* The Parser converts a Simple source program to the Sea of Nodes intermediate representation
@@ -61,41 +61,22 @@ public class Parser {
* Parse a primary expression:
*
* <pre>
- * primaryExpr : nestedExpr | integerLiteral
+ * primaryExpr : integerLiteral
* </pre>
*/
private Node parsePrimary(Lexer lexer) {
switch (_curTok._kind) {
- case PUNCT -> {
- /* Nested expression */
- return parseNestedExpr(lexer);
- }
case NUM -> {
return parseIntegerLiteral(lexer);
}
default -> {
- error(_curTok, "syntax error, expected nested expr or integer literal");
+ error(_curTok, "syntax error, expected integer literal");
return null;
}
}
}
/**
- * Parse nested expression:
- *
- * <pre>
- * nestedExpr : ( expr )
- * </pre>
- */
- private Node parseNestedExpr(Lexer lexer) {
- matchPunctuation(lexer, "(");
- nextToken(lexer);
- var node = parsePrimary(lexer);
- matchPunctuation(lexer, ")");
- return node;
- }
-
- /**
* Parse integer literal
*
* <pre>
@@ -229,11 +210,13 @@ public class Parser {
}
// First digit of a number.
- // Allows [-][1-9] but not a leading 0
+ // Allows 0 on its own or
+ // [-][1-9][0-9]*
private boolean isFirstNumber(char ch) {
char ch2 = peek();
- return ('1'<=ch && ch<='9') ||
- (ch=='-' && ('1'<=ch2 && ch2<='9'));
+ return (ch=='0' && (ch2 <'0' || ch2 > '9')) || // 0 followed by non-digit
+ ('1'<=ch && ch<='9') || // starts with [1-9]
+ (ch=='-' && ('1'<=ch2 && ch2<='9')); // starts with - and followed by [1-9]
}
private Token parseNumber() {
int start = _position-1;
@@ -278,12 +261,12 @@ public class Parser {
return Token.EOF;
if (isFirstNumber(ch))
return parseNumber();
- if (isIdentifierLetter(ch))
+ if (isIdentifierStart(ch))
return parseIdentifier();
if (isPunctuation(ch))
return parsePuncuation();
- throw error("Unknown token "+ch);
+ throw error("syntax error: unexpected input '" + ch + "'");
}
private RuntimeException error(String msg) {
diff --git a/chapter01/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter01/src/main/java/com/seaofnodes/simple/node/Node.java
index f817db52..6b2a19b8 100644
--- a/chapter01/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter01/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -1,7 +1,6 @@
package com.seaofnodes.simple.node;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
/**
diff --git a/chapter01/src/test/java/com/seaofnodes/simple/ParserTest.java b/chapter01/src/test/java/com/seaofnodes/simple/ParserTest.java
index 586c53de..029f6121 100644
--- a/chapter01/src/test/java/com/seaofnodes/simple/ParserTest.java
+++ b/chapter01/src/test/java/com/seaofnodes/simple/ParserTest.java
@@ -40,6 +40,15 @@ public class ParserTest {
}
@Test
+ public void testZero() {
+ Parser parser = new Parser();
+ StartNode start = parser.parse("return 0;");
+ for( Node use : start._outputs )
+ if( use instanceof ConstantNode con )
+ assertEquals(0,con._value);
+ }
+
+ @Test
public void testBad1() {
try { new Parser().parse("ret"); }
catch( RuntimeException e ) { assertEquals("syntax error, expected return: ret",e.getMessage()); }
@@ -48,12 +57,18 @@ public class ParserTest {
@Test
public void testBad2() {
try { new Parser().parse("return 0123;"); }
- catch( RuntimeException e ) { assertEquals("syntax error, expected nested expr or integer literal: 0123",e.getMessage()); }
+ catch( RuntimeException e ) { assertEquals("syntax error: unexpected input '0'",e.getMessage()); }
}
@Test
public void testBad3() {
try { new Parser().parse("return --12;"); }
- catch( RuntimeException e ) { assertEquals("syntax error, expected ( got --: --",e.getMessage()); }
+ catch( RuntimeException e ) { assertEquals("syntax error, expected integer literal: --",e.getMessage()); }
+ }
+
+ @Test
+ public void testBad4() {
+ try { new Parser().parse("return 100"); }
+ catch( RuntimeException e ) { assertTrue(e.getMessage().contains("syntax error, expected ; got :")); }
}
}