Skip to content

Commit 4e9fe07

Browse files
committed
remove repeated code and add comment to it
1 parent e916407 commit 4e9fe07

File tree

2 files changed

+125
-121
lines changed

2 files changed

+125
-121
lines changed

commentDFA.cpp

Lines changed: 89 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,137 @@
1-
// commentDFA.cpp
21

32
#include <iostream>
43
#include <fstream>
54
#include <string>
6-
#include <filesystem>
7-
#include <sstream>
8-
5+
#include <sstream>
96
#include "commentDFA.h"
107

8+
// Helper function: Read the next character and update line count
9+
bool getNextChar(std::ifstream& file, char& ch, int& lineCount) {
10+
file.get(ch);
11+
if (file.eof()) return false;
12+
if (ch == '\n') lineCount++;
13+
return true;
14+
}
15+
16+
// Helper function: Report error and terminate
17+
void reportError(const std::string& message, int errorLine) {
18+
std::cerr << "ERROR: " << message << " on line " << errorLine << std::endl;
19+
exit(1);
20+
}
21+
1122
// State 0: Normal state, reading and printing code character by character
1223
void CommentDFA::state0(std::ifstream& file, int& lineCount, std::ostringstream& buffer) {
13-
char ch;
14-
file.get(ch); // Read a character from the file
15-
if (file.eof()) { // Check if the end of file is reached
16-
buffer << "\n";
17-
return; // End of input, stop the function
18-
} else if (ch == '/') { // If the character is '/', move to state1
19-
return state1(file, lineCount, buffer);
20-
} else if (ch == '*'){
21-
if(!state6(file, lineCount, buffer)) {
22-
std::cerr << "ERROR: Program contains C-style, unterminated quote on line " << lineCount;
23-
exit(1);
24-
}
24+
char ch;
25+
if (!getNextChar(file, ch, lineCount)) {
26+
buffer << "\n"; // End of input
2527
return;
28+
}
29+
30+
if (ch == '/') {
31+
state1(file, lineCount, buffer);
32+
} else if (ch == '*') {
33+
if (!state6(file, lineCount, buffer)) {
34+
reportError("Program contains C-style, unterminated comment", lineCount);
35+
}
2636
} else if (ch == '"') {
27-
int quoteLineCount = 0;
2837
buffer << ch;
38+
int quoteLineCount = lineCount;
2939
if (!state5(file, lineCount, quoteLineCount, buffer)) {
30-
std::cerr << "ERROR: Program contains C-style, unterminated quote on line " << lineCount;
31-
exit(1);
32-
}
33-
return;
34-
} else { // Otherwise, print the character and stay in state0
35-
if (ch == '\n') {
36-
lineCount++;
40+
reportError("Program contains C-style, unterminated quote", quoteLineCount);
3741
}
42+
} else {
3843
buffer << ch;
39-
return state0(file, lineCount, buffer);
44+
state0(file, lineCount, buffer);
4045
}
4146
}
4247

43-
// State 1: After hitting a '/', figure out if it's a comment or a division operator
48+
// State 1: After encountering '/', decide if it's a comment or division operator
4449
void CommentDFA::state1(std::ifstream& file, int& lineCount, std::ostringstream& buffer) {
45-
char ch;
46-
file.get(ch); // Read the next character
47-
if (file.eof()) { // Check for end of file
48-
return;
49-
} else if (ch == '/') { // If it's another '/', we have a C++-style comment, move to state2
50-
buffer << " "; // Add whitespace
51-
return state2(file, lineCount, buffer);
52-
} else if (ch == '*') { // If it's a '*', we have a C-style block comment, move to state3
50+
char ch;
51+
if (!getNextChar(file, ch, lineCount)) return;
52+
53+
if (ch == '/') {
54+
buffer << " "; // Add whitespace for single-line comment
55+
state2(file, lineCount, buffer);
56+
} else if (ch == '*') {
57+
buffer << " "; // Add whitespace for block comment
58+
int startCommentLine = lineCount;
5359
int commentLineCount = 0;
54-
buffer << " "; // Add whitespace
55-
if (!state3(file, lineCount, commentLineCount, buffer)) {
56-
std::cerr << "ERROR: Program contains C-style, unterminated comment on line " << lineCount;
57-
exit(0);
58-
}
59-
return;
60-
} else { // Otherwise, it's just a '/', print it and return to state0
61-
if (ch == '\n') {
62-
lineCount++;
60+
if (!state3(file, lineCount, commentLineCount, startCommentLine, buffer)) {
61+
reportError("Program contains C-style, unterminated comment", startCommentLine);
6362
}
64-
buffer << '/'; // Don't forget to print the first '/' since it's not part of a comment
65-
buffer << ch; // Also print the current character
66-
return state0(file, lineCount, buffer);
63+
} else {
64+
buffer << '/' << ch;
65+
state0(file, lineCount, buffer);
6766
}
6867
}
6968

70-
// State 2: Inside a C++-style line comment, skip characters until newline is reached
69+
// State 2: Inside a C++-style single-line comment
7170
void CommentDFA::state2(std::ifstream& file, int& lineCount, std::ostringstream& buffer) {
72-
char ch;
73-
file.get(ch); // Read the next character
74-
if (ch == '\n') { // If it's a newline, return to state0 to process the next line
75-
lineCount++;
76-
buffer << "\n"; // Add newline
77-
return state0(file, lineCount, buffer);
78-
} else {
79-
buffer << " "; // Add whitespace
71+
char ch;
72+
if (!getNextChar(file, ch, lineCount) || ch == '\n') {
73+
buffer << "\n"; // End of single-line comment
74+
state0(file, lineCount, buffer);
75+
return;
8076
}
81-
return state2(file, lineCount, buffer); // Otherwise, stay in state2, ignoring characters
77+
buffer << " "; // Replace comment content with spaces
78+
state2(file, lineCount, buffer);
8279
}
8380

84-
// State 3: Inside a C-style block comment, look for the closing '*/'
85-
bool CommentDFA::state3(std::ifstream& file, int& lineCount, int& commentLineCount, std::ostringstream& buffer) {
86-
char ch;
87-
file.get(ch); // Read the next character
88-
if (ch == '*') { // If it's a '*', check if it's the start of '*/' (end of comment)
89-
return state4(file, lineCount, commentLineCount, buffer);
81+
// State 3: Inside a C-style block comment
82+
bool CommentDFA::state3(std::ifstream& file, int& lineCount, int& commentLineCount, int startCommentLine, std::ostringstream& buffer) {
83+
char ch;
84+
if (!getNextChar(file, ch, lineCount)) return false;
85+
86+
if (ch == '*') {
87+
return state4(file, lineCount, commentLineCount, startCommentLine, buffer);
9088
} else if (ch == '\n') {
91-
buffer << "\n"; // Add newline
89+
buffer << "\n";
9290
commentLineCount++;
93-
}else if (file.eof()){
94-
return false;
9591
} else {
96-
buffer << " "; // Add whitespace
92+
buffer << " ";
9793
}
98-
return state3(file, lineCount, commentLineCount, buffer); // Otherwise, stay in state3, ignoring characters
94+
return state3(file, lineCount, commentLineCount, startCommentLine, buffer);
9995
}
10096

101-
// State 4: Looking for '/' to close the C-style block comment
102-
bool CommentDFA::state4(std::ifstream& file, int& lineCount, int& commentLineCount, std::ostringstream& buffer) {
103-
char ch;
104-
file.get(ch); // Read the next character
105-
if (ch == '/') { // If it's '/', the block comment is closed, return to state0
106-
buffer << " "; // Add whitespace
107-
lineCount += commentLineCount;
97+
// State 4: Check for '/' to close the C-style block comment
98+
bool CommentDFA::state4(std::ifstream& file, int& lineCount, int& commentLineCount, int startCommentLine, std::ostringstream& buffer) {
99+
char ch;
100+
if (!getNextChar(file, ch, lineCount)) return false;
101+
102+
if (ch == '/') {
103+
buffer << " "; // Close block comment
108104
state0(file, lineCount, buffer);
109105
return true;
110-
} else if (ch == '\n') {
111-
buffer << "\n"; // Add newline
112-
commentLineCount++;
113-
} else if (file.eof()){
114-
return false;
115106
} else if (ch == '*') {
116107
file.putback(ch);
108+
} else {
109+
buffer << " ";
117110
}
118-
buffer << " "; // Add whitespace
119-
return state3(file, lineCount, commentLineCount, buffer); // Otherwise, continue checking inside the block comment
111+
return state3(file, lineCount, commentLineCount, startCommentLine, buffer);
120112
}
121113

122-
// State 5: Inside a quoted string (either single or double quotes),
123-
// ignore characters inside until the closing quote is found
114+
// State 5: Inside a quoted string
124115
bool CommentDFA::state5(std::ifstream& file, int& lineCount, int& quoteLineCount, std::ostringstream& buffer) {
125-
char ch;
126-
file.get(ch);
127-
if (file.eof()) { // If end of file is reached, return false
128-
return false;
129-
} else if (ch == '"') { // If a closing quote is found, return to state 0
130-
buffer << ch; // Output the character
131-
lineCount += quoteLineCount; // Increment the line counter
132-
state0(file, lineCount, buffer); // Go back to state 0
133-
return true; // And finally return true
134-
} else {
135-
buffer << ch; // Otherwise, go to state 5
136-
return state5(file, lineCount, quoteLineCount, buffer);
116+
char ch;
117+
if (!getNextChar(file, ch, lineCount)) return false;
118+
119+
buffer << ch;
120+
if (ch == '"') {
121+
state0(file, lineCount, buffer);
122+
return true;
137123
}
124+
return state5(file, lineCount, quoteLineCount, buffer);
138125
}
139126

140-
// State 6: Detected an asterisk ('*'),
141-
// check if it's an unterminated C-style block comment
127+
// State 6: Detected an asterisk ('*'), check for unterminated C-style block comment
142128
bool CommentDFA::state6(std::ifstream& file, int& lineCount, std::ostringstream& buffer) {
143-
char ch;
144-
file.get(ch);
145-
if (ch == '/') { // If a slash is found, return false
146-
return false;
147-
} else {
129+
char ch;
130+
if (!getNextChar(file, ch, lineCount) || ch != '/') {
148131
buffer << '*';
149-
file.putback(ch); // Otherwise, put the character back
150-
state0(file, lineCount, buffer); // Go to state 0
151-
return true; // And return true
132+
if (ch != '/') file.putback(ch);
133+
state0(file, lineCount, buffer);
134+
return true;
152135
}
136+
return false;
153137
}

commentDFA.h

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,49 @@
1-
// commentDFA.h
2-
#ifndef COMMENTDFA_H // include guard
3-
#define COMMENTDFA_H
1+
2+
#ifndef COMMENTDFA_H
3+
#define COMMENTDFA_H
44

55
#include <iostream>
66
#include <fstream>
77
#include <string>
8-
#include <filesystem>
9-
#include <sstream>
8+
#include <sstream>
109

10+
// Declaration of the CommentDFA class
1111
class CommentDFA
1212
{
1313
private:
14-
int lineCount = 1;
15-
// Function prototypes for the different DFA states
16-
void state0(std::ifstream& file, int& lineCount, std::ostringstream& buffer); // Normal state, reading code
17-
void state1(std::ifstream& file, int& lineCount, std::ostringstream& buffer); // Detected '/', checking if it's a comment
18-
void state2(std::ifstream& file, int& lineCount, std::ostringstream& buffer); // Inside a C++-style comment, ignore until newline
19-
bool state3(std::ifstream& file, int& lineCount, int& commentLineCount, std::ostringstream& buffer); // Inside a C-style block comment
20-
bool state4(std::ifstream& file, int& lineCount, int& commentLineCount, std::ostringstream& buffer); // Checking for end of C-style block comment
21-
bool state5(std::ifstream& file, int& lineCount, int& quoteLinecount, std::ostringstream& buffer); // Inside a quoted string, skip over characters until end of quote
22-
bool state6(std::ifstream& file, int& lineCount, std::ostringstream& buffer); // Detected Asterisk, check if unterminated comment
14+
int lineCount = 1; // Tracks the current line number being processed in the file
15+
16+
// State 0: Normal state, reading and processing code character by character
17+
void state0(std::ifstream& file, int& lineCount, std::ostringstream& buffer);
18+
19+
// State 1: Detecting a '/' to determine if it's the start of a comment or just a division operator
20+
void state1(std::ifstream& file, int& lineCount, std::ostringstream& buffer);
21+
22+
// State 2: Inside a C++-style comment, ignoring characters until the end of the line
23+
void state2(std::ifstream& file, int& lineCount, std::ostringstream& buffer);
24+
25+
// State 3: Inside a C-style block comment, processing until the closing '*/'
26+
bool state3(std::ifstream& file, int& lineCount, int& commentLineCount, int startCommentLine, std::ostringstream& buffer);
27+
28+
// State 4: Checking for the end of a C-style block comment by detecting '*/'
29+
bool state4(std::ifstream& file, int& lineCount, int& commentLineCount, int startCommentLine, std::ostringstream& buffer);
30+
31+
// State 5: Inside a quoted string, processing until the closing quote is found
32+
bool state5(std::ifstream& file, int& lineCount, int& quoteLineCount, std::ostringstream& buffer);
33+
34+
// State 6: Detected an asterisk ('*'), checking if it's part of an unterminated comment
35+
bool state6(std::ifstream& file, int& lineCount, std::ostringstream& buffer);
36+
2337
public:
24-
CommentDFA() {}
25-
~CommentDFA() { delete this; };
38+
// Default constructor
39+
CommentDFA() = default;
40+
41+
// Destructor
42+
~CommentDFA() = default;
43+
44+
// Entry point to start the DFA from State 0, initializing the process
2645
void begin(std::ifstream& file, std::ostringstream& buffer) { state0(file, lineCount, buffer); }
2746
};
2847

2948
#endif /* COMMENTDFA_H */
49+

0 commit comments

Comments
 (0)