简单的词法分析器

2017-03-19  本文已影响0人  hzxiao

任务

你将使用图转移算法手工实现一个小型的词法分析器。

程序

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

#define MAX_LINE 1024  //每行做大的字节数

//词法的类型
enum Kind {
    IF,
    ID,
    NUM
};

//存储每个词的信息的结构体
struct Token {
    enum Kind kind;
    char* value;
    int row;
    int col;
};

struct Token *Token_new(enum Kind kind, char *value, int row, int col) {
    struct Token *token = (struct Token*)malloc(sizeof(*token));
    token->value = (char*)malloc(sizeof(*value));
    strncpy(token->value, value, strlen(value));
    token->kind = kind;
    token->row = row;
    token->col = col;
    return token;
}
//用于存放所有词的链表结构
struct List {
    struct Token *token;
    struct List *next;
};

struct List *all_word;
struct List* List_new(struct Token* t, struct List* list) {
    struct List* p = (struct List*)malloc(sizeof(*p));
    p->token = t;
    p->next = list;
    return p;
}

void List_print(struct List* list) {
    if (!list) {
        return;
    }
    List_print(list->next);

    switch (list->token->kind) {
        case IF: {
            printf("IF (%d, %d)\n", list->token->row, list->token->col);
            break;
        }
        case ID: {
            printf("ID(%s) (%d, %d)\n", list->token->value, list->token->row, list->token->col);
            break;
        }
        case NUM: {
            printf("NUM(%s) (%d, %d)\n", list->token->value, list->token->row, list->token->col);
            break;
        }
        default:
            break;
    }
}

//处理单词
void Process_word(char *word, int len, int row, int col) {
    if (strcmp("if", word) == 0) {
        struct Token *token = Token_new(IF, word, row, col);
        all_word = List_new(token, all_word);
    }else if (Is_num(word, len) == 1) {
        struct Token *token = Token_new(NUM, word, row, col);
        all_word = List_new(token, all_word);
    } else {
        struct Token *token = Token_new(ID, word, row, col);
        all_word = List_new(token, all_word);
    }
}

//判断是否为数字
int Is_num(char* word, int len) {
    for (int i = 0; i < len; i++) {
        if (word[i] < '0' || word[i] > '9'){
            return 0;
        }
    }
    return 1;
}



int main() {
    FILE *file;
    char strLine[MAX_LINE];
    char str[MAX_LINE];
    if ((file = fopen("/home/hz/a.txt", "r")) == NULL) {
        printf("Open Failed!");
        return -1;
    }

    int curr_row = 0; //当前的行数
    while (!feof(file)) {
        curr_row++;

        if(fgets(strLine, MAX_LINE, file)){
            printf("%s", strLine);
            int len = strlen(strLine);
            int str_save_len = 0;
            for (int i = 0; i < len; i++) {
                char c = strLine[i];
                switch (c) {
                    case ' ': {
                        if (str_save_len > 0) {
                            str[str_save_len] = '\0';
                            Process_word(str, str_save_len, curr_row, i + 1);
                            str_save_len = 0;
                        }
                        break;
                    }
                    case '\n': {
                        if (str_save_len > 0) {
                            str[str_save_len] = '\0';
                            Process_word(str, str_save_len, curr_row, i + 1);
                            str_save_len = 0;
                        }
                        break;
                    }
                    default: {
                        str[str_save_len++] = c;
                    }
                }
            }

        }
    }

    List_print(all_word);
    fclose(file);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读