Skip to content

Commit fe55470

Browse files
committed
handle the nesting comments
1 parent d4d9597 commit fe55470

File tree

5 files changed

+111
-19
lines changed

5 files changed

+111
-19
lines changed

scanner/build/scanner_test

724 KB
Binary file not shown.

scanner/include/scanner.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,16 @@ namespace TINY
105105
void skipWhitespace();
106106

107107
/**
108-
* @brief Skips over comments in the input source code.
108+
* @brief Skips over nested comments in the input source code.
109109
*
110110
* This method checks if the current position is at the start of a comment (indicated by a '{' character).
111111
* If it is, the method skips over all characters until it finds the corresponding closing '}'.
112+
* It correctly handles **nested comments** by keeping track of the nesting levels.
113+
* For each opening '{', it increases the nesting level, and for each closing '}', it decreases the nesting level.
114+
* The comment is considered closed when the nesting level returns to zero.
112115
* After successfully skipping a comment, it also skips any whitespace characters that follow the comment.
113-
* If the end of the input is reached before finding a closing '}', the method returns `true` to indicate
114-
* that an unclosed comment was detected.
116+
* If the end of the input is reached before all comments are closed (i.e., nesting level does not return to zero),
117+
* the method returns `true` to indicate that an unclosed comment was detected.
115118
*
116119
* @return True if an unclosed comment was detected, false otherwise.
117120
*/

scanner/src/scanner.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "scanner.hpp"
1111
#include <cctype> // For character classification functions
1212
#include <stdexcept> // For exception handling (if needed)
13+
#include <stack>
1314

1415
namespace TINY
1516
{
@@ -184,23 +185,39 @@ namespace TINY
184185
{
185186
if (pos < input.size() && peek() == '{')
186187
{
187-
get(); // Consume '{'
188-
while (pos < input.size() && peek() != '}')
189-
{
190-
get(); // Consume characters inside the comment
191-
}
192-
if (pos < input.size())
193-
{
194-
get(); // Consume '}'
195-
skipWhitespace(); // Skip any whitespace after the comment
196-
return false; // Comment was successfully skipped
197-
}
198-
else
188+
get(); // Consume initial '{'
189+
std::stack<char> commentStack;
190+
commentStack.push('{'); // Push the initial '{' onto the stack
191+
192+
while (pos < input.size())
199193
{
200-
// EOF reached before closing '}'
201-
// Unclosed comment detected
202-
return true;
194+
char currentChar = get();
195+
196+
if (currentChar == '{')
197+
{
198+
commentStack.push('{'); // Push nested '{' onto the stack
199+
}
200+
else if (currentChar == '}')
201+
{
202+
commentStack.pop(); // Pop a '{' from the stack
203+
204+
if (commentStack.empty())
205+
{
206+
// All comments are closed
207+
skipWhitespace(); // Skip whitespace after comment
208+
return false; // Comment was successfully skipped
209+
}
210+
}
211+
else if (currentChar == '\0')
212+
{
213+
// End of input reached unexpectedly
214+
return true; // Unclosed comment detected
215+
}
216+
// Continue consuming characters inside the comment
203217
}
218+
219+
// EOF reached before all comments were closed
220+
return true; // Unclosed comment detected
204221
}
205222
return false; // No comment to skip
206223
}

scanner/test/scanner_test.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,5 +294,78 @@ namespace TINY
294294
EXPECT_FALSE(scanner.hasMoreTokens());
295295
}
296296

297+
// New test case: Nested comments
298+
TEST(ScannerTest, NestedComments)
299+
{
300+
// Input with nested comments
301+
std::string input = "read x; { This is a { nested { comment } } } write y;";
302+
303+
Scanner scanner(input);
304+
305+
// Token: read
306+
Token token1 = scanner.getNextToken();
307+
EXPECT_EQ(token1.getType(), TokenType::READ);
308+
EXPECT_EQ(token1.getValue(), "read");
309+
310+
// Token: x
311+
Token token2 = scanner.getNextToken();
312+
EXPECT_EQ(token2.getType(), TokenType::IDENTIFIER);
313+
EXPECT_EQ(token2.getValue(), "x");
314+
315+
// Token: ;
316+
Token token3 = scanner.getNextToken();
317+
EXPECT_EQ(token3.getType(), TokenType::SEMICOLON);
318+
EXPECT_EQ(token3.getValue(), ";");
319+
320+
// Nested comments are skipped, no tokens generated for them
321+
322+
// Token: write
323+
Token token4 = scanner.getNextToken();
324+
EXPECT_EQ(token4.getType(), TokenType::WRITE);
325+
EXPECT_EQ(token4.getValue(), "write");
326+
327+
// Token: y
328+
Token token5 = scanner.getNextToken();
329+
EXPECT_EQ(token5.getType(), TokenType::IDENTIFIER);
330+
EXPECT_EQ(token5.getValue(), "y");
331+
332+
// Token: ;
333+
Token token6 = scanner.getNextToken();
334+
EXPECT_EQ(token6.getType(), TokenType::SEMICOLON);
335+
EXPECT_EQ(token6.getValue(), ";");
336+
337+
EXPECT_FALSE(scanner.hasMoreTokens());
338+
}
339+
340+
// New test case: Unclosed nested comment
341+
TEST(ScannerTest, UnclosedNestedComment)
342+
{
343+
// Input with an unclosed nested comment
344+
std::string input = "read x; { Outer comment { Inner comment } write y;";
345+
346+
Scanner scanner(input);
347+
348+
// Token: read
349+
Token token1 = scanner.getNextToken();
350+
EXPECT_EQ(token1.getType(), TokenType::READ);
351+
EXPECT_EQ(token1.getValue(), "read");
352+
353+
// Token: x
354+
Token token2 = scanner.getNextToken();
355+
EXPECT_EQ(token2.getType(), TokenType::IDENTIFIER);
356+
EXPECT_EQ(token2.getValue(), "x");
357+
358+
// Token: ;
359+
Token token3 = scanner.getNextToken();
360+
EXPECT_EQ(token3.getType(), TokenType::SEMICOLON);
361+
EXPECT_EQ(token3.getValue(), ";");
362+
363+
// Attempt to get next token, should return UNKNOWN due to unclosed comment
364+
Token token4 = scanner.getNextToken();
365+
EXPECT_EQ(token4.getType(), TokenType::UNKNOWN);
366+
EXPECT_EQ(token4.getValue(), "Unclosed comment");
367+
368+
EXPECT_FALSE(scanner.hasMoreTokens());
369+
}
297370
} // namespace SCANNER
298371
} // namespace TINY

scanner/test/token_test.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,5 @@ namespace TINY
2525
EXPECT_EQ(token.toString(false), "if, IF");
2626
EXPECT_EQ(token.toString(true), "if, IF [Line: 1, Column: 1]");
2727
}
28-
2928
} // namespace SCANNER
3029
} // namespace TINY

0 commit comments

Comments
 (0)