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

如何使用yacc/bison实现非结构化距离数据到公制单位的转换

基于Bison/Yacc实现非结构化距离解析的方案

你需要配合Flex(词法分析器)和Bison(语法分析器)完成解析,核心逻辑是先拆分输入的有效词元,再按规则累加换算为米的数值。


1. 先定义Flex词法规则

首先用Flex过滤无效内容、拆分数字、单位等有效词元,示例规则如下:

%option noyywrap
%{
#include "distance.tab.h"
%}

%%
/* 忽略无意义的修饰前缀 */
"about"|"around"               { }

/* 匹配小数、分数,返回数值token */
[0-9]+(\.[0-9]+)?              { yylval.dval = atof(yytext); return NUM; }
[0-9]+"/"[0-9]+                { int a,b; sscanf(yytext, "%d/%d", &a, &b); yylval.dval = (double)a / b; return NUM; }

/* 匹配各类单位变体,返回单位token */
"m"|"meter"|"meters"           { return METER; }
"mile"|"miles"                 { return MILE; }
"y"|"yd"|"yard"|"yards"        { return YARD; }

/* 忽略空白字符 */
[ \t\n]+                       { }
%%

2. 再定义Bison语法规则

Bison侧负责完成单位换算和数值累加,支持多段距离、带分数等场景,示例规则如下:

%{
#include <stdio.h>
static double total_meter = 0;
%}

/* 指定token值的类型为double */
%define api.value.type {double}
%token NUM METER MILE YARD

%%
/* 距离可由多个数值+单位的组合组成,累加所有换算后的值 */
distance: /* 空输入 */
        | distance expr { total_meter += $2; }
        ;

/* 单个数值+单位的换算规则,包含带分数适配 */
expr: NUM METER          { $$ = $1 * 1.0; }
    | NUM MILE           { $$ = $1 * 1609.34; }
    | NUM YARD           { $$ = $1 * 0.9144; }
    | NUM NUM METER      { $$ = ($1 + $2) * 1.0; }
    | NUM NUM MILE       { $$ = ($1 + $2) * 1609.34; }
    | NUM NUM YARD       { $$ = ($1 + $2) * 0.9144; }
    ;
%%

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

/* 对外暴露的转换函数,输入原始字符串返回米为单位的数值 */
double convert_to_meter(const char *input) {
    total_meter = 0;
    YY_BUFFER_STATE buf = yy_scan_string(input);
    yyparse();
    yy_delete_buffer(buf);
    return total_meter;
}

3. 适配效果验证

你提到的三类输入都可以正常解析:

  • about 2 1/4 miles:忽略about,计算(2 + 0.25) * 1609.34 = 3621.015米
  • 1 mile 40 yards:分段计算1*1609.34 + 40*0.9144 = 1645.916米
  • 5m 10y:分段计算5*1 + 10*0.9144 = 14.144米

如果需要新增支持的单位,只需要在Flex中加单位匹配规则、Bison中加对应的换算规则即可,无需修改整体逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:27:01