Flex Manual基础笔记3

1. 例子1git

功能:从标准输入读取一行,分析出其中包含的数字个数和字母个数。函数

/* filename: input.lex */
%{
    int digitCount = 0;
    int letterCount = 0;
%}
digit [0-9]
letter [a-zA-Z]
newline \n
%%
{digit} digitCount++;
{letter} letterCount++;
{newline}   return 0;
%%
int yywrap() { return 1;}
    /* main */
int main() {
    yylex();
    printf("Numbers: %d, Letters: %d\n", digitCount, letterCount);
    return 0;
}

 测试运行:

#flex input.lex 
#gcc lex.yy.c 
#./a.out 
123abc456defgh
Numbers: 6, Letters: 8
#

说明:理解yylex()函数的做用,其用于进行扫描,每次调用yylex()都是从上一次扫描结束的地方开始。对于这里,只调用了一次,因此就是从标准输入的第一个字符开始扫描。那么,其什么时候返回呢?遇到return或者文件结束才会返回,因此这里须要newline时候return 0,不然,程序无法结束。

2. 例子2测试

实际的编译器工做的流程,通常来讲扫描器扫描到匹配的token都须要返回,通过一些处理,而后继续扫描,并且通常的编译器的输入都是文件。下面实现一个相似的例子,以文件做为输入,固然,这里不修改输出,通常输出都会结合其余接口去使用,好比yacc。flex

/* filename: input.lex */
%{
    int digitCount = 0;
    int letterCount = 0;
    #define TOKENDIGIT  1
    #define TOKENLETTER  2
%}
digit [0-9]
letter [a-zA-Z]
newline \n
%%
{digit} digitCount++;return TOKENDIGIT;
{letter} letterCount++;return TOKENLETTER;
    /*{newline}   return 0;*/
%%
int yywrap() { return 1;}
void setInputfile(const char* filename) {
    FILE* fp = fopen(filename, "r");
    if (filename == NULL || fp == NULL) {
        printf("Cannot open source file\n");
        exit(0);
    }
    yyin = fp;
}
    /* main */
int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Only and must accept 1 auguments\n");
        exit(0);
    }
    setInputfile(argv[1]);

    int token = yylex();
    while(token != 0) {
        printf("Token type: %d, token: %s, token length: %d\n", token, yytext, yyleng);
        token = yylex();    // get next token
    }

    printf("Numbers: %d, Letters: %d\n", digitCount, letterCount);
    return 0;
}

测试运行:

#flex input.lex 
#gcc lex.yy.c 
#cat test.txt 
1ab
2d
3f
#./a.out test.txt 
Token type: 1, token: 1, token length: 1
Token type: 2, token: a, token length: 1
Token type: 2, token: b, token length: 1

Token type: 1, token: 2, token length: 1
Token type: 2, token: d, token length: 1

Token type: 1, token: 3, token length: 1
Token type: 2, token: f, token length: 1

Numbers: 3, Letters: 4
#
PS:若是读到文件尾,那么yylex()返回值为0,因此这里是while(token != 0)
相关文章
相关标签/搜索