You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flex和Bison统计单词中的字符重复次数

Flex+Bison实现单词字符重复次数统计实现思路

整个实现不需要设计复杂的语法规则,核心把词法切分、计数逻辑拆到Flex、Bison两层分别实现即可,具体落地步骤如下:

Flex层(词法分析)实现

  • 核心负责切分输入流,把非单词内容全部过滤:匹配空白符(空格、换行、制表符)、常用标点时直接跳过,不向Bison传递任何token
  • 匹配连续字母组成的单词序列时,将匹配到的字符串通过yylval传递给Bison,对应token标记为WORD即可
  • 匹配到输入结束符<<EOF>>时返回0,通知Bison输入处理完成
  • 记得实现yywrap函数返回1,避免编译时出现链接错误

Flex端核心规则代码参考:

%{
#include "y.tab.h"
%}

%%
[a-zA-Z]+  { 
    yylval.str = strdup(yytext); 
    return WORD; 
}
[ \t\n\r,.!?;:"'()\[\]{}]+  { 
    /* 跳过所有单词分隔符、标点符号 */ 
}
<<EOF>>    { return 0; }
%%

int yywrap() {
    return 1;
}

Bison层(语法处理+统计逻辑)实现

  • 前置定义:将yylval的联合体类型中增加字符串指针成员,用于接收Flex传递的单词内容;定义长度为256的整型数组作为计数器,对应ASCII全字符集的出现次数,初始值全部置0
  • 语法规则做极简设计即可:产生式只需要定义输入为0个或多个WORD的序列,每匹配到一个WORD,就遍历字符串的每一个字符,对应计数器下标的值累加1,遍历完成后释放Flex通过strdup分配的字符串内存,避免内存泄漏
  • 所有输入解析完成后,遍历计数器数组,输出所有出现次数≥2的字符及其出现次数即可

Bison端核心代码参考:

%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 字符出现次数计数器,下标对应ASCII值
int char_cnt[256] = {0};

void yyerror(const char *err) {
    fprintf(stderr, "解析错误: %s\n", err);
}
%}

%union {
    char *str;
}

%token <str> WORD

%%

input:
    | input WORD {
        char *cur = $2;
        while (*cur != '\0') {
            char_cnt[(unsigned char)*cur]++;
            cur++;
        }
        free($2);
    }
    ;

%%

int main() {
    yyparse();
    printf("=== 字符重复统计结果 ===\n");
    for (int i = 0; i < 256; i++) {
        if (char_cnt[i] >= 2) {
            printf("字符 '%c' 重复出现,总次数: %d\n", i, char_cnt[i]);
        }
    }
    return 0;
}

适配调整说明

如果你的需求是统计单个单词内部的字符重复次数,而非全局所有文本的字符总重复次数,只需要调整计数器的重置时机:每次匹配到新的WORD时先把计数器数组全量置0,遍历完当前单词的所有字符后立刻打印该单词的统计结果,再继续处理下一个单词即可。

编译执行的命令参考:

bison -d count.y
flex count.l
gcc lex.yy.c y.tab.c -o char_count -lfl
# 执行后直接输入文本,按Ctrl+D触发EOF即可输出统计结果
./char_count

内容的提问来源于stack exchange,提问作者Deaa Jahjah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:36:27