Untitled

 avatar
unknown
plain_text
4 months ago
7.6 kB
1
Indexable
#include <stdlib.h>

#define MAX_SYMBOLS 100
#define MAX_INPUT_LENGTH 100
#define MAX_STACK_SIZE 100

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

// Define Token Types
typedef enum {
    KEYWORD,
    IDENTIFIER,
    CONSTANT,
    OPERATOR,
    DELIMITER,
    UNKNOWN
} TokenType;

// List of sample keywords (you can expand this list)
const char *keywords[] = {"int", "float", "char", "void", "return", "if", "else", "while", "for"};
const int keyword_count = 9;

// Stack for operators in expression evaluation
typedef struct {
    char items[MAX_STACK_SIZE];
    int top;
} Stack;

void initStack(Stack* s) {
    s->top = -1;
}

int isEmpty(Stack* s) {
    return s->top == -1;
}

void push(Stack* s, char item) {
    if (s->top < MAX_STACK_SIZE - 1) {
        s->items[++s->top] = item;
    }
}

char pop(Stack* s) {
    if (isEmpty(s)) {
        return -1;
    }
    return s->items[s->top--];
}

char peek(Stack* s) {
    if (isEmpty(s)) {
        return -1;
    }
    return s->items[s->top];
}

// Function to display the symbol table
void displayTable(struct Symbol symbols[], int count) {
    printf("\n============================= SYMBOL TABLE =============================\n");
    printf("| %-5s | %-20s | %-10s | %-15s |\n", "Index", "Name", "DataType", "Scope");
    printf("==========================================================================\n");
    for (int i = 0; i < count; i++) {
        printf("| %-5d | %-20s | %-10s | %-15s |\n", symbols[i].index, symbols[i].name, symbols[i].dataType, symbols[i].scope);
    }
    printf("==========================================================================\n");
}

// Function to insert a new symbol into the symbol table
void insertSymbol(struct Symbol symbols[], int *count) {
    if (*count >= MAX_SYMBOLS) {
        printf("\nError: Symbol table is full!\n");
        return;
    }
    
    struct Symbol newSymbol;
    newSymbol.index = *count + 1;

    printf("Enter identifier name: ");
    scanf("%s", newSymbol.name);
    
    printf("Enter data type: ");
    scanf("%s", newSymbol.dataType);
    
    printf("Enter scope: ");
    scanf("%s", newSymbol.scope);
    
    symbols[*count] = newSymbol;
    (*count)++;
    
    printf("\nSymbol inserted successfully!\n");
}

// Function to check if a character is an operator
int isOperator(char c) {
    return (c == '+' || c == '-' || c == '*' || c == '/' || c == '%');
}

// Function to check precedence of operators
int precedence(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

// Convert infix expression to postfix
void infixToPostfix(char* infix, char* postfix) {
    Stack s;
    initStack(&s);
    int j = 0;
    
    for (int i = 0; i < strlen(infix); i++) {
        char current = infix[i];
        
        if (isalnum(current)) {
            postfix[j++] = current;  // Add operand (variable or constant)
        }
        else if (current == '(') {
            push(&s, current);  // Push '(' to stack
        }
        else if (current == ')') {
            while (!isEmpty(&s) && peek(&s) != '(') {
                postfix[j++] = pop(&s);  // Pop until '('
            }
            pop(&s);  // Discard '('
        }
        else if (isOperator(current)) {
            while (!isEmpty(&s) && precedence(peek(&s)) >= precedence(current)) {
                postfix[j++] = pop(&s);  // Pop operators based on precedence
            }
            push(&s, current);  // Push current operator
        }
    }

    // Pop remaining operators from the stack
    while (!isEmpty(&s)) {
        postfix[j++] = pop(&s);
    }
    postfix[j] = '\0';  // Null-terminate the postfix expression
}

// Generate Three Address Code (TAC)
void generateTAC(char* infix) {
    char postfix[MAX_INPUT_LENGTH];
    infixToPostfix(infix, postfix);

    printf("\n==================== THREE ADDRESS CODE ====================\n");
    int tempCounter = 1;
    Stack s;
    initStack(&s);

    for (int i = 0; i < strlen(postfix); i++) {
        char current = postfix[i];
        
        if (isalnum(current)) {
            push(&s, current);  // Push operands (variables/constants)
        } 
        else if (isOperator(current)) {
            char operand2 = pop(&s);  // Pop second operand
            char operand1 = pop(&s);  // Pop first operand
            printf("t%d = %c %c %c\n", tempCounter++, operand1, current, operand2);  // Print TAC
            push(&s, 't' + (tempCounter - 1));  // Push the temporary variable
        }
    }
    printf("==============================================================\n");
}

// Main function with menu options
int main() {
    struct Symbol symbols[MAX_SYMBOLS];
    int symbolCount = 0;
    int choice;
    
    while (1) {
        printf("\n======================= MENU =======================\n");
        printf("1. Insert symbol\n");
        printf("2. Display symbol table\n");
        printf("3. Lexical analysis (tokenize code)\n");
        printf("4. Convert expression to postfix and generate TAC\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                insertSymbol(symbols, &symbolCount);
                break;
            case 2:
                displayTable(symbols, symbolCount);
                break;
            case 3: {
                char code[MAX_INPUT_LENGTH];
                printf("Enter code to tokenize (e.g., int x = 10;): ");
                getchar();  // To consume the newline character from previous input
                fgets(code, MAX_INPUT_LENGTH, stdin);
                
                printf("\n========================= TOKENS ==========================\n");
                for (int i = 0; i < strlen(code); i++) {
                    if (isspace(code[i])) continue;  // Skip spaces
                    if (isalpha(code[i])) {
                        printf("%c - IDENTIFIER\n", code[i]);
                    }
                    else if (isdigit(code[i])) {
                        printf("%c - CONSTANT\n", code[i]);
                    }
                    else if (isOperator(code[i])) {
                        printf("%c - OPERATOR\n", code[i]);
                    }
                    else {
                        printf("%c - DELIMITER\n", code[i]);
                    }
                }
                break;
            }
            case 4: {
                char expression[MAX_INPUT_LENGTH];
                printf("Enter an expression: ");
                getchar();  // To consume the newline character from previous input
                fgets(expression, MAX_INPUT_LENGTH, stdin);

                printf("\n======================= POSTFIX =======================\n");
                char postfix[MAX_INPUT_LENGTH];
                infixToPostfix(expression, postfix);
                printf("Postfix Expression: %s\n", postfix);

                generateTAC(expression);
                break;
            }
            case 5:
                printf("Exiting...\n");
                return 0;
            default:
                printf("Invalid choice. Please try again.\n");
        }
    }

    return 0;
}
Editor is loading...
Leave a Comment