Projects/1BIT/summer-semester/IJC-1/no-comment.c
2026-04-14 19:28:46 +02:00

163 lines
4.5 KiB
C

// no-comment.c
// Řešení IJC-DU1, příklad b), 22.3.2024
// Autor: Roman Nečas, FIT
// Přeloženo: gcc 13.2.1
#include <stdio.h>
#include "error.h"
int main(int argc, char *argv[])
{
FILE *fp;
int state = 0;
int c;
int lastChar = 0; // To keep track of the last character to handle line continuation in comments
if (argc > 2)
{
error_exit("Too many arguments");
}
if(argc == 2)
{
fp = fopen(argv[1], "r");
if (!fp) {
error_exit("Cannot open file: %s", argv[1]);
}
}
else
{
fp = stdin;
}
while ((c = fgetc(fp)) != EOF)
{
switch (state)
{
case 0: // Normal code
if (c == '/')
{
state = 1; // Possible comment start
}
else if (c == '"')
{
putchar(c);
state = 4; // String literal start
}
else if (c == '\'') // Handle single quotes
{
putchar(c);
state = 7; // Character literal start
}
else
{
putchar(c);
}
break;
case 1: // After first '/'
if (c == '*')
{
state = 2; // Multi-line comment start
}
else if (c == '/')
{
// Transition to single-line comment state but do not output '/'
state = 6; // Single-line comment start
}
else
{
putchar('/'); // Not a comment, print '/' and current char
putchar(c);
state = 0;
}
break;
case 2: // Inside multi-line comment
if (c == '*')
{
state = 3; // Possible end of comment
}
break;
case 3: // Possible end of multi-line comment
if (c == '/')
{
state = 0; // End of comment
}
else if (c != '*')
{
state = 2; // Still inside comment
}
break;
case 4: // Inside string literal
if (c == '\\')
{
putchar(c);
c = fgetc(fp); // Read next character
putchar(c); // Print escaped character
// Do not change state, stay in string literal
}
else if (c == '"')
{
putchar(c); // End of string literal
state = 0;
}
else
{
putchar(c); // Part of string literal
}
break;
case 5: // After escape character in string literal
putchar(c); // Print escaped character
state = 4;
break;
case 6: // Inside single-line comment
if (c == '\n')
{
if (lastChar != '\\') // If not a continuation
{
putchar(c); // Ensure newline is outputted to maintain original structure
state = 0; // End of single-line comment
}
// If it was a continuation, simply ignore and continue in state 6
}
break;
case 7: // Inside character literal
putchar(c);
if (c == '\\')
{
state = 8; // Escape sequence within character literal
}
else if (c == '\'')
{
state = 0; // End of character literal
}
break;
case 8: // After escape character in character literal
putchar(c); // Print escaped character
state = 7; // Return to character literal state
break;
}
lastChar = c; // Update lastChar at the end of the loop
}
if (ferror(fp))
{
error_exit("Read error\n");
}
if (state != 0)
{
error_exit("Unterminated comment or string\n");
}
fclose(fp);
return 0;
}