From 1d0b1274fd36973ff9d4d90027ac52b22c121910 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Sat, 1 Aug 2026 17:41:46 +0100 Subject: [PATCH] Fix unsubstituted '%s' in error message for 'for' loop missing 'in' When a for-statement's target is not followed by 'in' and there are no more tokens on the line (e.g. just 'for x'), ParserState.reportError's TokenBuffer overload reports TOKEN_REQUIRED with only one of its two required parameters, since the auto-padding logic in _reportError is bypassed once the token stream is exhausted. String.format then throws and the raw template ('%s' required but '%s' found.) is shown verbatim. Report MISSING_TOKEN instead in that case, matching the same convention already used by TokenBuffer.requireType for an exhausted token stream. --- .../src/main/scala/tigerpython/parser/parsing/Parser.scala | 5 ++++- tpParser/shared/src/test/programs/erroneous/for_loop_04.txt | 3 +++ tpParser/shared/src/test/scala/TestErroneousPrograms.scala | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tpParser/shared/src/test/programs/erroneous/for_loop_04.txt diff --git a/tpParser/shared/src/main/scala/tigerpython/parser/parsing/Parser.scala b/tpParser/shared/src/main/scala/tigerpython/parser/parsing/Parser.scala index 4779510..800db2a 100755 --- a/tpParser/shared/src/main/scala/tigerpython/parser/parsing/Parser.scala +++ b/tpParser/shared/src/main/scala/tigerpython/parser/parsing/Parser.scala @@ -1434,7 +1434,10 @@ class Parser(val source: CharSequence, parserState.reportError(line.startPos, ErrorCode.FOREIGN_SYNTAX, "Pascal") return null } else { - parserState.reportError(tokens, ErrorCode.TOKEN_REQUIRED, "in") + if (tokens.hasNext) + parserState.reportError(tokens, ErrorCode.TOKEN_REQUIRED, "in") + else + parserState.reportError(tokens.endPos, ErrorCode.MISSING_TOKEN, "in") if (expressionParser.firstOfTest(tokens)) expressionParser.parseTestListAsTuple(tokens) else diff --git a/tpParser/shared/src/test/programs/erroneous/for_loop_04.txt b/tpParser/shared/src/test/programs/erroneous/for_loop_04.txt new file mode 100644 index 0000000..2dfde6b --- /dev/null +++ b/tpParser/shared/src/test/programs/erroneous/for_loop_04.txt @@ -0,0 +1,3 @@ +# 1 +# MISSING_TOKEN +for x diff --git a/tpParser/shared/src/test/scala/TestErroneousPrograms.scala b/tpParser/shared/src/test/scala/TestErroneousPrograms.scala index cb43e1f..1d83dee 100644 --- a/tpParser/shared/src/test/scala/TestErroneousPrograms.scala +++ b/tpParser/shared/src/test/scala/TestErroneousPrograms.scala @@ -100,5 +100,7 @@ class TestErroneousPrograms extends FunSuite { } assert(cs.get.line+1 == line_no) assert(cs.get.errorCode.toString == error_msg) + // The error message must have all of its '%s' placeholders substituted with actual values + assert(!cs.get.errorMessage.contains("%s"), s"un-substituted placeholder in message: ${cs.get.errorMessage}") } }