From d3ffe6f9a935888233283962ce077ec25a01bec9 Mon Sep 17 00:00:00 2001 From: Yichen Yan Date: Wed, 1 Nov 2023 22:08:30 +0800 Subject: Bail out unclosed block (#25) * Report unclosed block in parsing * Fix tests * Resolve comments and rebase onto chapter5 * Test `isEOF` after consume whitespaces --- .../src/main/java/com/seaofnodes/simple/Parser.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'chapter03/src/main/java/com/seaofnodes') diff --git a/chapter03/src/main/java/com/seaofnodes/simple/Parser.java b/chapter03/src/main/java/com/seaofnodes/simple/Parser.java index 12e156ed..3d06a9c3 100644 --- a/chapter03/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter03/src/main/java/com/seaofnodes/simple/Parser.java @@ -39,7 +39,7 @@ public class Parser { } public ReturnNode parse() { - return (ReturnNode) parseBlock(); + return (ReturnNode) parseBlock(false); } @@ -50,14 +50,22 @@ public class Parser { * '{' statements '}' * */ - private Node parseBlock() { + private Node parseBlock(boolean requireClosingBracket) { // Enter a new scope _scope.push(); Node n = null; - while (!match("}") && !_lexer.isEOF()) { + do { + if (match("}")) { + if (requireClosingBracket) break; + else throw error("unexpected '}' token"); + } else if (_lexer.isEOF()) { + if (requireClosingBracket) require("}"); + else break; + } + Node n0 = parseStatement(); if (n0 != null) n = n0; // Allow null returns from eg showGraph - } + } while (true); // Exit scope _scope.pop(); return n; @@ -73,7 +81,7 @@ public class Parser { private Node parseStatement() { if (match("return")) return parseReturn(); else if (match("int")) return parseDecl(); - else if (match("{")) return parseBlock(); + else if (match("{")) return parseBlock(true); else if (match("#showGraph")) return showGraph(); else return parseExpressionStatement(); } -- cgit v1.2.3