Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình C

Phân tích từ vựng (Lexical Analysis) phát hiện token trong C

Chương trình C phát hiện các token (từ khóa, định danh, hằng số, toán tử, phân cách) trong code C. Đây là giai đoạn phân tích từ vựng của trình biên dịch.

Các loại token

  • Từ khóa: if, else, while, int, float, return,...
  • Định danh: tên biến, hàm (bắt đầu bằng chữ/cạch dưới)
  • Hằng nguyên: 123, -456
  • Hằng thực: 3.14, -0.5
  • Toán tử: +, -, *, /, =, ==, <, >,...
  • Phân cách: ;, ,, (, ), {, }, [, ]

Chương trình mẫu

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

bool isDelimiter(char c) {
    return strchr(" +-*/,;><=()[]{}", c) != NULL;
}

bool isOperator(char c) {
    return strchr("+-*/><=", c) != NULL;
}

bool isKeyword(char* s) {
    char* kw[] = {"if","else","while","do","break","continue","int","double",
                  "float","return","char","case","sizeof","long","short",
                  "typedef","switch","unsigned","void","static","struct","goto"};
    for (int i=0; i<22; i++) if (strcmp(s, kw[i])==0) return true;
    return false;
}

bool isInteger(char* s) {
    for (int i=0; s[i]; i++)
        if (s[i]<'0' || s[i]>'9') return false;
    return true;
}

bool isReal(char* s) {
    bool dot = false;
    for (int i=0; s[i]; i++) {
        if (s[i]=='.') { if (dot) return false; dot=true; }
        else if (s[i]<'0' || s[i]>'9') return false;
    }
    return dot;
}

bool isIdentifier(char* s) {
    if (s[0]>='0' && s[0]<='9') return false;
    if (isDelimiter(s[0])) return false;
    return true;
}

void detectTokens(char* str) {
    int len = strlen(str), left=0, right=0;
    while (right <= len && left <= right) {
        if (right < len && !isDelimiter(str[right])) { right++; continue; }
        
        if (right < len && isDelimiter(str[right]) && left==right) {
            if (isOperator(str[right])) printf("Toán tử: '%c'\n", str[right]);
            right++; left=right;
        } else if ((right==len || isDelimiter(str[right])) && left!=right) {
            char* sub = strndup(str+left, right-left);
            if (isKeyword(sub)) printf("Từ khóa: '%s'\n", sub);
            else if (isInteger(sub)) printf("Số nguyên: '%s'\n", sub);
            else if (isReal(sub)) printf("Số thực: '%s'\n", sub);
            else if (isIdentifier(sub)) printf("Định danh: '%s'\n", sub);
            else printf("Lỗi: '%s'\n", sub);
            free(sub);
            left = right;
        }
    }
}

int main() {
    char code[] = "float x = a + 1b;";
    printf("Code: %s\nToken:\n", code);
    detectTokens(code);
    return 0;
}

Kết quả

Code: float x = a + 1b;
Token:
Từ khóa: 'float'
Định danh: 'x'
Toán tử: '='
Định danh: 'a'
Toán tử: '+'
Lỗi: '1b'

Lưu ý: Đây là lexical analyzer đơn giản, không xử lý comment, chuỗi, ký tự escape, toán tử nhiều ký tự (==, <=, ++,...). Trình biên dịch thực phức tạp hơn nhiều.