学习《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++++++++
++++++++++++++++++++++++++