flex学习1

学习《lex与yacc(第2版)》时,根据第一章节04小结,重写了如下用例,用于理解和加深对flex的掌握。

# cat test1.l
%{
/*symbol table to recognize words */
enum {
    LOOKUP = 0,
    VERB,
    ADJ,
    ADV,
    NOUN,
    PREP,
    PRON,
    CONJ
};

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int state;
int add_word(int type, char *word);
int lookup_word(char *word);
void show_all_wordlist(void);
void clear_all_wordlist(void);
void quit(void);
%}

%%
\n {state = LOOKUP;}
^verb {state = VERB;}
^adj {state = ADJ;}
^adv {state = ADV;}
^noun {state = NOUN;}
^prep {state = PREP;}
^pron {state = PRON;}
^conj {state = CONJ;}
^show {show_all_wordlist();}
^clear {clear_all_wordlist();}
^quit {quit();}

[a-zA-Z]+ {
    if (state != LOOKUP) {
        /* define current word*/ 
        add_word(state, yytext);
    } else {
        switch (lookup_word(yytext)) {
        case VERB: printf("%s: verb\n", yytext);
            break;
        case ADJ: printf("%s: adj\n", yytext); 
            break;
        case ADV: printf("%s: adv\n", yytext);
            break;
        case NOUN: printf("%s: noun\n", yytext);
            break;
        case PREP: printf("%s: prep\n", yytext);
            break;
        case PRON: printf("%s: pron\n", yytext);
            break;
        case CONJ: printf("%s: conj\n", yytext);
            break;
        default: printf("%s: dont recognize\n", yytext);
            break;
        }
    }
}
%%

int main(int argc, char *const argv[])
{
    yylex();
    return 0;
}

struct word {
    char *word_name;
    int word_type;
    struct word *next;
};

struct word *word_list = NULL;
extern void *malloc();

int 
add_word(int type, char *word)
{
    struct word *wp;

    if (lookup_word(word) != LOOKUP) {
        printf("warning: word %s already defined\n", word);
        return 0;
    }
    
    wp = (struct word *)malloc(sizeof(struct word));
    memset(wp, 0, sizeof(struct word));

    wp->next = word_list;

    wp->word_name = (char *)malloc(strlen(word) + 1);
    strcpy(wp->word_name, word);

    wp->word_type = type;
    word_list = wp;
    printf("add %s to word_list\n", word);
    return 1;
}

int
lookup_word(char *word)
{
    struct word *wp = word_list;

    for (wp = word_list; wp; wp = wp->next) {
        if (strcmp(wp->word_name, word) == 0) {
            return wp->word_type;  
        }
    }
    return LOOKUP;
}

void
show_all_wordlist(void)
{
    struct word *wp = NULL;

    printf("+++++++show wordlist++++++\n");
    for (wp = word_list; wp; wp = wp->next) {
        switch (wp->word_type) {
        case VERB: printf("%s is verb\n", wp->word_name); break;
        case ADJ: printf("%s is adj\n", wp->word_name); break;
        case ADV: printf("%s is adv\n", wp->word_name); break;
        case NOUN: printf("%s is noun\n", wp->word_name); break;
        case PREP: printf("%s is prep\n", wp->word_name); break;
        case PRON: printf("%s is pron\n", wp->word_name); break;
        case CONJ: printf("%s is conj\n", wp->word_name); break;
        default: printf("%s is unknown\n", wp->word_name); break;
        }
    }
    printf("++++++++++++++++++++++++++\n");
}

void free_word(struct word **list, char *word)
{
    struct word *current = NULL;
    struct word *prev = NULL;

    for (current = *list; current; current = prev->next) {
        if (0 != strcmp(current->word_name, word)) {
            prev = current;
            continue; 
        }
        if (current == *list) {
            *list = current->next;
        } else {
            prev->next = current->next; 
        }
        free(current->word_name);
        free(current);
        break;
    }
}
void 
clear_all_wordlist(void)
{
    printf("++++++++clear list++++++++\n");
    while (word_list) {
        switch (word_list->word_type) {
        case VERB: printf("%s is verb, clear\n", word_list->word_name); break;
        case ADJ: printf("%s is adj, clear\n", word_list->word_name); break;
        case ADV: printf("%s is adv, clear\n", word_list->word_name); break;
        case NOUN: printf("%s is noun, clear\n", word_list->word_name); break;
        case PREP: printf("%s is prep, clear\n", word_list->word_name); break;
        case PRON: printf("%s is pron, clear\n", word_list->word_name); break;
        case CONJ: printf("%s is conj, clear\n", word_list->word_name); break;
        default: printf("%s is unknown, clear\n", word_list->word_name); break;
        }

        free_word(&word_list, word_list->word_name);
    }
    printf("++++++++++++++++++++++++++\n");
}

void 
quit(void)
{
    clear_all_wordlist();
    exit(0);
}

编译:

[root@localhost ~/test/flex_bison/flex/ch1-04]
# flex test1.l; gcc -g *.c -o test1 -lfl

运行和测试:

[root@localhost ~/test/flex_bison/flex/ch1-04]
# ./test1 
verb is am are was were be go do
 add is to word_list
 add am to word_list
 add are to word_list
 add was to word_list
 add were to word_list
 add be to word_list
 add go to word_list
 add do to word_list



show
+++++++show wordlist++++++
do is verb
go is verb
be is verb
were is verb
was is verb
are is verb
am is verb
is is verb
++++++++++++++++++++++++++

is
is: verb

go
go: verb

clear
++++++++clear list++++++++
do is verb, clear
go is verb, clear
be is verb, clear
were is verb, clear
was is verb, clear
are is verb, clear
am is verb, clear
is is verb, clear
++++++++++++++++++++++++++


show
+++++++show wordlist++++++
++++++++++++++++++++++++++

is
is: dont recognize

quit
++++++++clear list++++++++
++++++++++++++++++++++++++
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值