flex & biosn 2

出自:lex和yacc(第二版)例子,

文件1:

[root@localhost ~/test/flex_bison/flex/ch1-05]
# cat test1.l
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "test1.tab.h"

#define LOOKUP (0)

int state;
int lookup_word(char *word);
int add_word(int type, char *word);
%}

%%
\n {state = LOOKUP;}

\.\n {
    state = LOOKUP;
    return 0; /*meaning the sentence end*/
}

^verb {state = VERB;}
^adj {state = ADJ;}
^adv {state = ADV;}
^noun {state = NOUN;}
^prep {state = PREP;}
^pron {state = PRON;}
^conj {state = CONJ;}

[a-zA-Z]+ {
    if (state != LOOKUP) {
        add_word(state, yytext);
    } else {
        switch (lookup_word(yytext)) {
        case VERB: return VERB; 
        case ADJ: return ADJ; 
        case ADV: return ADV; 
        case NOUN: return NOUN; 
        case PREP: return PREP; 
        case PRON: return PRON; 
        case CONJ: return CONJ; 
        default: printf("%s: dont recognize\n", yytext);
        }
    }
}

. /*ignore anything*/ ;
%%
#if 0
int main(int argc, char *const argv[])
{
    yylex();
    return 0;
}
#endif

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

struct word *word_list = NULL;

extern void *malloc();

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

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

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

    if (LOOKUP != lookup_word(word)) {
        printf("%s has already existed\n", word);
        return 0; 
    }

    printf("add %s[type: %d]\n", word, type);
    wp = (struct word *)malloc(sizeof(struct word));

    memset(wp, 0, sizeof(struct word));

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

    wp->word_type = type; 
    wp->next = word_list;

    word_list = wp;
    return 1;
}

文件2:

[root@localhost ~/test/flex_bison/flex/ch1-05]
# cat test1.y
%{
#include <stdio.h>
void yyerror(char *s);
%}

%token NOUN PRON VERB ADV ADJ PREP CONJ

%%
sentence: subject VERB object {printf("Sentence is valid.\n");}
        ;

subject: NOUN 
       | PRON 
       ;

object: NOUN 
      ;

%%

extern FILE *yyin;

int main(int argc, char *const argv[])
{
    do {
        yyparse();
    } while(!feof(yyin));
    return 0;
}


void
yyerror(char *s)
{
    fprintf(stderr, "Error: %s!!\n", s);
}

编译:

[root@localhost ~/test/flex_bison/flex/ch1-05]
# flex *.l; bison -d *.y; gcc *.c -o test1 -lfl
[root@localhost ~/test/flex_bison/flex/ch1-05]
# ls
lex.yy.c  test1  test1.l  test1.tab.c  test1.tab.h  test1.y

执行:

[root@localhost ~/test/flex_bison/flex/ch1-05]
# ./test1 
verb is be
add is[type: 260]
add be[type: 260]

noun book
add book[type: 258]

book is book
Sentence is valid.

book is book .
Sentence is valid.

*.y文件中
%%和%%之间的为规则段,每条规则都有“:”操作左侧的一个名字、右侧的符号列表和动作代码,以及指示规则结尾的分号组成。
默认情况下,第一条规则是最高级别的规则。

当词法分析程序报告输入结束时,词法分析程序会返回到他的调用程序中,在这里,是主程序。

随后,对yyparse()的调用重置状态,并在此开始处理。因为sentence是最高层次的符号,所以整个输入必须匹配sentence。
如果看到输入标记的“subject VERB object”列表,将打印一条消息“Sentence is valid.”;如果看到“subject subject",语法分析程序将调用yyerror()(用户的子程序中提供),将打印”Error: syntax error!!“。yyparse()在发现错误后,返回到调用程序。

*.y的第三部分,即用户子程序段,包含任意C代码,并且被逐字地复制到最终的语法分析程序中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值