用lex统计文本文件字符数

我曾经在Linux上写的一个C程序,借助Lex做词法分析来同时统计N个文本文件的字符数,单词数和行数。让我觉得Lex确实挺有意思的。确实Lex的功能非常强大,用来做小巧的词法分析非常适合,也非常好用。这个程序参考了《Lex与Yacc》上的一个例子。

%{
unsigned int char_count = 0, word_count = 0, line_count = 0;
%}
%%
[^ /t/n]+ {word_count++; char_count+=yyleng;};
/n {char_count++; line_count++;};
.  char_count++;
%%
char **file_list;
unsigned int current_file = 0;
unsigned int total_file = 0;

unsigned int total_cc = 0;
unsigned int total_wc = 0;
unsigned int total_lc = 0;

typedef struct file_info{
    unsigned int c;
    unsigned int w;
    unsigned int l;
    char *name;
}INFO;

INFO **all;


int create_info(int num)
{
    INFO *tmp;
    int i;
    if (num <= 0){
        return -1;
    }
    all = (INFO **)malloc(sizeof(int *)*num);
    for (i = 0; i < num; i++){
        tmp = (INFO *)malloc(sizeof(INFO));
        tmp->c = 0;
        tmp->w = 0;
        tmp->l = 0;
        tmp->name = NULL;
        all[i] = tmp;
    }
    return 1;
}    

int delete_info(int num)
{
    int i;
    if ((all == (INFO **)0) || num <= 0){
        return -1;
    }
    for (i = 0; i < num; i++){
        free(all[i]);
    }
    free(all);
    return 1;
}

int set_info(int pos)
{
    int length = 0;
    if (pos < 0){
        return -1;
    }
    all[pos]->c = char_count;
    all[pos]->w = word_count;
    all[pos]->l = line_count;    
    all[pos]->name = file_list[pos]; 
    
    return 1;
}

int main(int argc, char** argv)
{
    FILE *file;    
    int position = 0;
    int i;
    
    file_list = argv + 1;
    total_file = argc - 1;
    current_file = 0;
    
    printf("--------------------------------------------------------------/n",
 total_file);   
   
    if (argc > 1){
        if (create_info(total_file) == -1){
            fprintf(stderr, "%s/n", "Encounter a error when malloc memory.");

            exit(1);
        } 
    }
    if (argc == 2){               
        
        file=fopen(argv[1], "r");
        if (!file){
            fprintf(stderr, "Could not open %s./n", argv[1]);
            delete_info(total_file);
            exit(1);
        }        
        yyin = file;
    }
    
    yywrap();
    yylex();
   
    if (argc > 1){
        total_cc += char_count;
        total_wc += word_count;
        total_lc += line_count;        
        
        if (set_info(current_file-1) == -1){
            fprintf(stderr, "%s/n", "Encounter a error when set information to
 INFO.");
            delete_info(total_file);
            exit(1);
        }        
        
        for (i = 0; i < total_file; i++){
            printf("char:%-8lu word:%-8lu line:%-8lu file name:%s/n", all[i]->
c, all[i]->w, all[i]->l, file_list[i]);
        }
        printf("----------------------- total --------------------------------
/n");
        printf("chars:%-8lu words:%-8lu lines:%-8lu files:%d/n", total_cc, tot
al_wc, total_lc, total_file);
    }else{        
        printf("char:%-8lu word:%-8lu line:%-8lu/n", char_count, word_count, l
ine_count);
    }
    
    delete_info(total_file);
    return 0;
}
 
yywrap()
{
    FILE *file = NULL;
    
    if ((current_file > 0) && (current_file < total_file) && (total_file > 1))
{
        total_cc += char_count;
        total_wc += word_count;
        total_lc += line_count;
        
        if (set_info(current_file-1) == -1){
            fprintf(stderr, "%s/n", "Encounter a error when set information to
 INFO.");
            delete_info(total_file);
            exit(1);
        }    
        
        char_count = word_count = line_count = 0;
        fclose(yyin);        
    }
    while ((file_list[current_file] != (char *)0) && (current_file < total_fil
e)){
        
        file = fopen(file_list[current_file++], "r");
        if (!file){
            fprintf(stderr, "could not open %s .", file_list[current_file - 1]
);
        }else{
            yyin = file;
            break;
        }
    }
    return (file? 0 : 1);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Lex是一种词法分析器生成工具,它可以帮助我们进行文本的词法分析。利用Lex可以计算文本文件字符等信息。 首先,我们需要定义一个Lex规则文件,来描述要分析的文本文件的语法。在这个规则文件中,我们可以定义各种词法规则,如匹配行、匹配单词、匹配字等。 然后,我们使用Lex工具来生成词法分析器代码。Lex会根据我们定义的规则文件生成对应的分析器程序。我们可以在生成的代码的框架上进行修改,添加一些逻辑,来计算字符等信息。 在生成的分析器程序中,我们可以利用计器来统计字符。每当Lex匹配到一个字符时,我们就可以递增计器的值。 在分析器程序的其他位置,我们可以添加一些逻辑来计算其他信息,比如统计、单词等。在匹配到对应的词法规则时,我们就可以递增相应的计器。 最后,我们可以在程序执行完毕后,输出计器的值,得到字符等信息。 总的来说,利用Lex计算文本文件字符等信息的步骤如下: 1. 定义一个Lex规则文件,描述要分析的文本文件的语法。 2. 使用Lex工具生成词法分析器代码。 3. 在生成的代码中添加逻辑,计算字符等信息。 4. 执行分析器程序,输出字符等信息。 通过以上步骤,我们可以方便地利用Lex计算文本文件字符等信息。 ### 回答2: 利用Lex(也称作Flex)可以很方便地计算文本文件字符等信息。Lex是一种常用的词法分析器生成器,可以根据用户定义的正则表达式规则,将输入文本文件分解为一系列的词法单元(token)。 要计算文本文件字符,可以使用Lex根据规则将所有的字符逐个读入,并统计量。我们可以编写一个简单的Lex规则如下: ``` %{ int characters = 0; %} %% . { characters++; } %% int main(int argc, char** argv) { yylex(); printf("字符:%d\n", characters); return 0; } ``` 在这个例子中,首先定义一个整型变量`characters`来记录字符。在规则`.`中,用花括号括起来的代码`{ characters++; }`会在每读入一个字符时被执行,也就是说每读入一个字符字符加一。 编译并运行上述代码后,它将会分析输入的文本文件,并输出字符统计结果。 除了字符,利用Lex还可以计算文本文件中的行、单词等信息。只需要根据具体需求编写相应的规则,进行相应的处理即可。例如,要计算文本文件的行,可以在Lex规则中增加一个计器,在遇到换行符时进行加一操作。 总之,利用Lex可以很方便地编写对文本文件进行词法分析的程序,根据具体需求提取所需信息,并进行统计和分析。 ### 回答3: 要利用lex进行文本文件字符等计算,可以按照以下步骤进行: 1. 首先,创建一个lex源文件,命名为"count_lex.l"。 2. 在该文件中,定义需要统计字符的正则表达式模式。例如,可以使用"."来匹配所有的字符。 3. 在源文件中添加一个计器变量,用于统计字符量。 4. 创建一个规则来匹配这些字符,并在规则中每次匹配成功时,将计器加1。 5. 在规则匹配完所有字符后,加入结束文件的规则,当文件结束时,输出计器的值。 6. 编译和生成lex程序。 下面是一个示例的count_lex.l文件的代码: ``` %{ #include <stdio.h> int charCount = 0; %} %% . { charCount++; } \n ; /* 忽略换行符 */ %% int main(int argc, char *argv[]) { if (argc < 2) { printf("请提供文件名作为参。\n"); return 1; } FILE *file = fopen(argv[1], "r"); if (file == NULL) { printf("无法打开文件。\n"); return 1; } yyin = file; yylex(); fclose(file); printf("字符: %d\n", charCount); return 0; } ``` 要执行该程序,需要先安装lex来编译生成一个可执行文件。假设源文件为count_lex.l,执行以下命令生成可执行文件: ``` lex count_lex.l gcc lex.yy.c -o count_lex ``` 然后,可以输入以下命令来计算文本文件字符: ``` ./count_lex 文件名 ``` 其中,"文件名"是要计算字符文本文件的名字。执行完毕后,程序将输出字符的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值