Untitled

 avatar
unknown
plain_text
4 months ago
7.4 kB
2
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX_SYMBOLS 100
#define MAX_INPUT 256
#define MAX_TOKEN_LEN 50

// Symbol table structure
struct Symbol {
    int index;
    char name[50];
    char dataType[20];
    char scope[50];
};

struct Symbol symbolTable[MAX_SYMBOLS];
int symbolCount = 0;
int tempCount = 0;

// List of C keywords
char* keywords[] = {"int", "float", "if", "else", "while", "for", "return", NULL};

// Function prototypes
void displayMenu();
void lexicalAnalysis();
void symbolTableGenerator();
void threeAddressCodeGeneration();
void addSymbol(const char *, const char *, const char *);
void displaySymbolTable();
void insertSymbol();
char* newTemp();
void generateTAC(char *exp);
int isKeyword(char* str);
void printToken(char* token, char* type);

int main() {
    int choice;
    do {
        system("clear"); // For Linux/Mac. Use "cls" for Windows.
        displayMenu();
        printf("\nEnter your choice: ");
        scanf("%d", &choice);
        getchar(); // To consume the newline character after input

        switch (choice) {
            case 1:
                lexicalAnalysis();
                break;
            case 2:
                symbolTableGenerator();
                break;
            case 3:
                threeAddressCodeGeneration();
                break;
            case 0:
                printf("\nExiting...\n");
                break;
            default:
                printf("\nInvalid choice! Try again.\n");
        }

        if (choice != 0) {
            printf("\nPress Enter to return to the main menu...");
            getchar();
        }

    } while (choice != 0);

    return 0;
}

void displayMenu() {
    printf("============================\n");
    printf("  Compiler Design Project  \n");
    printf("============================\n");
    printf("1. Lexical Analysis\n");
    printf("2. Symbol Table Generator\n");
    printf("3. Three Address Code Generation\n");
    printf("0. Exit\n");
    printf("============================\n");
}

int isKeyword(char* str) {
    for (int i = 0; keywords[i] != NULL; i++) {
        if (strcmp(str, keywords[i]) == 0) {
            return 1; // It's a keyword
        }
    }
    return 0;
}

void printToken(char* token, char* type) {
    printf("Token: %-15s Type: %-10s\n", token, type);
}

void lexicalAnalysis() {
    char code[MAX_INPUT];
    char token[MAX_TOKEN_LEN];
    int tokenIndex = 0;
    int i = 0;

    printf("\n=== Lexical Analysis ===\n");
    printf("Enter the code to perform lexical analysis:\n");
    fgets(code, MAX_INPUT, stdin);
    code[strcspn(code, "\n")] = '\0'; // Remove the trailing newline character

    while (code[i] != '\0') {
        if (isspace(code[i])) {
            i++; // Skip whitespace
            continue;
        }

        // If it's a digit (for numbers)
        if (isdigit(code[i])) {
            token[tokenIndex++] = code[i++];
            while (isdigit(code[i])) { // Handle multi-digit numbers
                token[tokenIndex++] = code[i++];
            }
            token[tokenIndex] = '\0';
            printToken(token, "NUMBER");
            tokenIndex = 0;
            continue;
        }

        // If it's a letter (for identifiers or keywords)
        if (isalpha(code[i])) {
            token[tokenIndex++] = code[i++];
            while (isalnum(code[i])) { // Handle multi-character identifiers
                token[tokenIndex++] = code[i++];
            }
            token[tokenIndex] = '\0';

            if (isKeyword(token)) {
                printToken(token, "KEYWORD");
            } else {
                printToken(token, "IDENTIFIER");
            }
            tokenIndex = 0;
            continue;
        }

        // If it's an operator or punctuation
        if (strchr("+-*/=><!;,()[]{}", code[i])) {
            token[tokenIndex++] = code[i++];
            token[tokenIndex] = '\0';
            printToken(token, "OPERATOR");
            tokenIndex = 0;
            continue;
        }

        // Handle invalid characters
        printf("Invalid character: %c\n", code[i]);
        i++;
    }
}

void symbolTableGenerator() {
    int choice;
    while (1) {
        printf("\n=== Symbol Table Generator ===\n");
        printf("1. Insert symbol\n");
        printf("2. Display symbol table\n");
        printf("3. Return to main menu\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                insertSymbol();
                break;
            case 2:
                displaySymbolTable();
                break;
            case 3:
                return;
            default:
                printf("Invalid choice. Please try again.\n");
        }
    }
}

void insertSymbol() {
    if (symbolCount >= MAX_SYMBOLS) {
        printf("Symbol table is full!\n");
        return;
    }

    struct Symbol newSymbol;
    newSymbol.index = symbolCount + 1;

    printf("Enter identifier name: ");
    scanf("%s", newSymbol.name);

    printf("Enter data type: ");
    scanf("%s", newSymbol.dataType);

    printf("Enter scope: ");
    scanf("%s", newSymbol.scope);

    symbolTable[symbolCount++] = newSymbol;
    printf("Symbol inserted successfully!\n");
}

void displaySymbolTable() {
    printf("\nSymbol Table:\n");
    printf("-----------------------------\n");
    printf("| Index | Name    | DataType | Scope   |\n");
    printf("-----------------------------\n");
    for (int i = 0; i < symbolCount; i++) {
        printf("| %-5d | %-6s | %-8s | %-7s |\n", symbolTable[i].index, symbolTable[i].name, symbolTable[i].dataType, symbolTable[i].scope);
    }
    printf("-----------------------------\n");
}

char* newTemp() {
    char *temp = (char *)malloc(10 * sizeof(char));
    sprintf(temp, "t%d", tempCount++);
    return temp;
}

void generateTAC(char *exp) {
    char operators[] = {'+', '-', '*', '/'};
    char stack[100][100];
    int top = -1;

    for (int i = 0; exp[i] != '\0'; i++) {
        if (exp[i] == ' ' || exp[i] == '(') continue;

        if (exp[i] >= 'a' && exp[i] <= 'z') {
            // Operand (Variable)
            stack[++top][0] = exp[i];
            stack[top][1] = '\0';
        } else if (strchr(operators, exp[i]) != NULL) {
            // Operator
            if (top >= 1) {
                char *op2 = stack[top--];
                char *op1 = stack[top--];
                char *temp = newTemp();

                printf("%s = %s %c %s\n", temp, op1, exp[i], op2);
                stack[++top][0] = temp[0];
                stack[top][1] = temp[1];
                stack[top][2] = '\0';
            }
        }
    }

    if (top == 0) {
        printf("Result: %s\n", stack[top]);
    }
}

void threeAddressCodeGeneration() {
    char expression[100];

    printf("\n=== Three Address Code Generation ===\n");
    printf("Enter the expression: ");
    fgets(expression, sizeof(expression), stdin);
    expression[strcspn(expression, "\n")] = '\0'; // Remove newline character

    generateTAC(expression);
}

Editor is loading...
Leave a Comment