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

如何在YACC中获取当前匹配的规则文本?

在YACC中获取匹配的declaration完整字符串的方法

YACC本身不会自动保存匹配规则的完整字符串,需要配合LEX记录每个token的文本内容,再在YACC的动作中拼接得到完整的declaration字符串,具体实现步骤如下:

1. 定义YACC的语义值类型

在YACC文件开头,通过%union定义语义值结构体,用来存储每个token的文本:

%union {
    char* str;
}
// 指定每个token对应的语义值字段
%token <str> TYPE INSTANCE SEMICOLON

2. 修改LEX规则,保存token文本

在LEX文件中,让每个识别到的token把自身文本复制到语义值中,示例如下:

[a-zA-Z_][a-zA-Z0-9_]*    {
    // 这里需要根据你的语法逻辑判断当前token是type还是instance
    if (is_type_keyword(yytext)) { // 假设你有判断类型关键字的自定义函数
        yylval.str = strdup(yytext);
        return TYPE;
    } else {
        yylval.str = strdup(yytext);
        return INSTANCE;
    }
}
";"    {
    yylval.str = strdup(yytext);
    return SEMICOLON;
}

3. 在YACC的declaration动作中拼接字符串

在declaration规则的动作里,将type、instance、SEMICOLON对应的文本拼接,得到完整的声明字符串:

declaration: type instance SEMICOLON
{
    // 计算所需内存长度,包含空格和字符串结束符
    int total_len = strlen($1) + strlen($2) + strlen($3) + 2;
    char* full_decl = malloc(total_len);
    if (full_decl != NULL) {
        // 拼接成完整的声明字符串
        snprintf(full_decl, total_len, "%s %s%s", $1, $2, $3);
        // 此处可对full_decl进行打印、存储等操作
        puts(full_decl);
        // 释放拼接后的字符串内存
        free(full_decl);
    }
    // 释放每个token的文本内存,避免泄漏
    free($1);
    free($2);
    free($3);
}

type: TYPE { $$ = $1; }
instance: INSTANCE { $$ = $1; }

注意事项

  • 内存管理:strdup会分配堆内存,所有通过该函数生成的字符串都需要手动调用free释放。
  • 复杂语法适配:如果type或instance由多个token组成(比如long long或int* var),需要在对应的子规则中先完成子部分的字符串拼接,再传递给上层规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:15:39