diff options
| author | dibyendumajumdar <mobile@majumdar.org.uk> | 2023-09-19 19:25:12 +0100 |
|---|---|---|
| committer | dibyendumajumdar <mobile@majumdar.org.uk> | 2023-09-19 19:25:12 +0100 |
| commit | bf82e7a511cd1f2ab739f75b4dcf536478591f09 (patch) | |
| tree | 239e680ecdb4c1fe518551e9ef3388d2f3b08c45 /chapter01 | |
| parent | fd9d039662a788903233faf8a7dcb37d14d29aaa (diff) | |
| download | Simple-bf82e7a511cd1f2ab739f75b4dcf536478591f09.tar.gz Simple-bf82e7a511cd1f2ab739f75b4dcf536478591f09.zip | |
Parse standalone 0 as integer
Diffstat (limited to 'chapter01')
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 :")); } } } |
