Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdbool.h>
- #define MAX_WORD 256
- #define MAX_FILE_SIZE 10000
- typedef enum {
- START, SIGN, DECIMAL, OCTAL, HEX_PREFIX, HEX, FLOAT, EXPONENT, EXPONENT_SIGN, EXPONENT_DIGITS, SUFFIX, UNSIGNED, INVALID
- } State;
- int invalidType = 0;
- int startType = 1;
- int signType = 2;
- int integerType = 3;
- int octalType = 4;
- int hex_prefixType = 5;
- int hexType = 6;
- int floatType = 7;
- int exponentType = 8;
- int exponent_signType = 9;
- int exponent_digitsType = 10;
- int suffixType = 11;
- int unsignedType = 12;
- int longType = 13;
- // Функция за класификация на числа чрез FSM
- int classify_number(const char *str, int *type, int *second_type) {
- int state = startType;
- int i = 0;
- bool is_unsigned = false, has_dot = false, has_exponent = false, is_real = false;
- while (str[i] != '\0') {
- char c = str[i];
- switch (state) {
- case 1:
- if (c == '+' || c == '-') {
- state = signType;
- } else if (c == '0') {
- state = octalType;
- } else if (isdigit(c)) {
- state = integerType;
- } else if (c == '.') {
- state = floatType;
- has_dot = true;
- } else {
- return invalidType;
- }
- break;
- case 2:
- if (isdigit(c)) {
- state = integerType;
- } else if (c == '.') {
- state = floatType;
- has_dot = true;
- } else {
- return invalidType;
- }
- break;
- case 3:
- if (isdigit(c)) {
- // Оставаме в десетично състояние
- } else if (c == '.') {
- state = floatType;
- has_dot = true;
- } else if (tolower(c) == 'e') {
- state = exponentType;
- has_exponent = true;
- } else if (tolower(c) == 'u') {
- if(str[0] == '+' || isdigit(str[0])) {
- state = unsignedType;
- }
- } else if (tolower(c) == 'l') {
- state = longType;
- } else if (tolower(c) == 'c') {
- return invalidType;
- } else {
- return invalidType;
- }
- break;
- case 4:
- if (c >= '0' && c <= '7') {
- // Оставаме в осмично състояние
- } else if (tolower(c) == 'x') {
- state = hex_prefixType;
- } else if (tolower(c) == 'u' || tolower(c) == 'l') {
- if(tolower(c) == 'u') {
- *second_type = unsignedType;
- }
- } else {
- return invalidType;
- }
- break;
- case 5:
- if (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f')) {
- state = hexType;
- } else {
- return invalidType;
- }
- break;
- case 6:
- if (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f')) {
- // Оставаме в шестнадесетично състояние
- } else if (tolower(c) == 'u' || tolower(c) == 'l') {
- state = unsignedType;
- } else {
- return invalidType;
- }
- break;
- case 7:
- if (isdigit(c)) {
- // Оставаме в състоянието FLOAT
- } else if (tolower(c) == 'e') {
- state = exponentType;
- has_exponent = true;
- } else {
- return invalidType;
- }
- break;
- case 8:
- if (c == '+' || c == '-') {
- state = exponent_signType;
- } else if (isdigit(c)) {
- state = exponent_digitsType;
- } else {
- return invalidType;
- }
- break;
- case 9:
- if (isdigit(c)) {
- state = exponent_digitsType;
- } else {
- return invalidType;
- }
- break;
- case 10:
- if (isdigit(c)) {
- // Оставаме в експоненциално състояние
- } else {
- return invalidType;
- }
- break;
- case 11:
- if (tolower(c) == 'l') {
- // UL, ULL вариант
- } else {
- return invalidType;
- }
- break;
- case 12:
- if(isdigit(c)) {
- return invalidType;
- } else {
- if(tolower(c) == 'l') {
- *second_type = longType;
- } else if (tolower(c) == 'c' ) {
- return invalidType;
- }
- }
- break;
- case 13:
- if(isdigit(c) || (tolower(c) != 'u' && tolower(c) != 'l')) {
- return invalidType;
- } else {
- if(tolower(c) == 'u' && (isdigit(str[0]) || str[0] == '+')) {
- *second_type = unsignedType;
- } else {
- return invalidType;
- }
- }
- break;
- default:
- return invalidType;
- }
- i++;
- }
- // Определяне на типа на числото
- if (has_dot || has_exponent) {
- *type = 6; // Float число
- if (str[strlen(str) - 1] == '0' && has_dot) {
- *type = 7; // Реално число
- }
- } else if (state == integerType) {
- *type = 1; // Десетично цяло число
- } else if (state == octalType) {
- *type = 2; // Осмично число
- } else if (state == hexType) {
- *type = 3; // Шестнадесетично число
- } else if (state == longType) {
- *type = 8; // Беззнаково число
- } else if (state == unsignedType) {
- *type = 4; // Беззнаково число
- } else {
- return invalidType;
- }
- return state;
- }
- // Главна функция (четене от файл)
- int main(int argc, char *argv[]) {
- if (argc != 2) {
- printf("Usage: %s <filename>\n", argv[0]);
- return 1;
- }
- FILE *test_FSM_2025_ = fopen(argv[1], "r");
- if (!test_FSM_2025_) {
- perror("Error opening file");
- return 1;
- }
- char line[MAX_FILE_SIZE];
- int total_count = 0, decimal_count = 0, octal_count = 0, hex_count = 0, float_count = 0;
- int unsigned_count = 0, integer_count = 0, real_count = 0, long_count = 0;
- while (fgets(line, sizeof(line), test_FSM_2025_)) {
- char *token = strtok(line, " ,\n"); // Разделяме по интервал, запетая и нов ред
- while (token != NULL) {
- int type = 0;
- int second_type = 0;
- if(strcmp(token, "0") == 0) {
- total_count++;
- integer_count++;
- } else if (classify_number(token, &type, &second_type) != invalidType) {
- total_count++;
- if (type == 1) decimal_count++;
- else if (type == 2) {
- octal_count++;
- if(second_type == 12) {
- printf("%s ", token);
- unsigned_count++;
- }
- }
- else if (type == 3) {
- hex_count++;
- }
- else if (type == 4) {
- printf("%s ", token);
- unsigned_count++;
- if(second_type == 13) {
- long_count++;
- }
- }
- else if (type == 6) float_count++; // Float числа
- else if (type == 7) real_count++; // Реални числа
- else if (type == 8) {
- long_count++;
- if(second_type == unsignedType) {
- printf("%s ", token);
- unsigned_count++;
- }
- }
- else if (type != 6 && type != 7) {
- integer_count++;
- } // Цели числа
- }
- token = strtok(NULL, " ,\n");
- }
- }
- fclose(test_FSM_2025_);
- printf("Total numbers: %d\n", total_count);
- printf("Integer constants: %d\n", integer_count);
- printf("Decimal constants: %d\n", decimal_count);
- printf("Octal constants: %d\n", octal_count);
- printf("Hexadecimal constants: %d\n", hex_count);
- printf("Unsigned integer constants: %d\n", unsigned_count);
- printf("Floating point constants: %d\n", float_count);
- printf("Real numbers: %d\n", real_count);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment