美文网首页
简单的词法分析器

简单的词法分析器

作者: hzxiao | 来源:发表于2017-03-19 21:10 被阅读0次

任务

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

  • 分析器的输入:存储在文本文件中的字符序列,字符取自ASCII字符集。文件中可能包括下面几种记号:关键字if、符合C语言标准的标识符、无符号整型数字、空格符、回车符\n。
  • 分析器的输出:打印出所识别的记号的种类、及记号开始行号、开始列号信息。
    注意:1. 忽略空格及回车符;2. 对于标识符和数字,要输出符号的具体词法单元(见下面的示例)。
    【示例】对于下面的文本文件:
    ifx if iif if 234
    iff if
    你的输出应该是(注意,因为文本显示的原因,列号信息可能不一定准确):
    ID(ifx) (1, 1)
    IF (1, 4)
    ID(iif) (1, 8)
    IF (1, 13)
    NUM(234) (1, 16)
    ID(iff) (2, 1)
    IF (2, 8)

程序

#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;
}

相关文章

  • 一个编译器最简前端的python实现

    一个编译器的前端通常包括词法分析器和语法分析器。在分析过程中,文本输入词法分析器,根据词法规则解析出词法单元。词法...

  • PHP核心理解-flex和bison入门

    一般词法分析器和语法分析器会一起使用,语法分析器会调用词法分析器来读取输入,词法分析器匹配到特定的模式后,就向语法...

  • 三. Flex进阶:需要了解的一些知识

    参考:词法分析器生成工具flex词法分析器总结--flex&bison词法分析生成器flex的选项 1. Flex...

  • 龙书 第三章

    词法单元:词法分析器扫描源程序并输出一个由词法单元组成的序列。这些词法单元通常会逐个传送给语法分析器。有些词法单元...

  • 自己动手制作C 语言编译器(3):词法分析器

    本章我们要讲解如何构建词法分析器。 什么是词法分析器 简而言之,词法分析器用于对源码字符串做预处理,以减少语法分析...

  • 编译原理->词法分析

    词法分析器的作用 词法分析器的主要任务是读入源程序的输入字符、将它们组成词素,生成并输出一个词法单元序列,每个词法...

  • 词法分析

    词法分析 词法分析器:字符流->记号流 词法分析器的手工构造比较符号的转移图转移图.png标识符的转移图转移图标识...

  • 简单的词法分析器

    任务 你将使用图转移算法手工实现一个小型的词法分析器。 分析器的输入:存储在文本文件中的字符序列,字符取自ASCI...

  • 一个简单的词法分析器(带界面)

    Java实现简单的词法分析器: 需求分析5类符号保留字(keywords):if、int、for、while、do...

  • 编译原理(一) Lexical analysis

    词法分析器的作用 词素(Lexeme)词法单元(Token): Token-name + Attribute-va...

网友评论

      本文标题:简单的词法分析器

      本文链接:https://www.haomeiwen.com/subject/smpmnttx.html