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

使用Flex和Bison(C++)开发简单字符串输出程序时遭遇yylex函数参数过多编译错误求助

使用Flex和Bison(C++)开发简单字符串输出程序时遭遇yylex函数参数过多编译错误求助

嘿,我来帮你搞定这个编译错误!这个问题的核心是Flex生成的yylex函数和Bison C++骨架期望的接口不匹配,咱们一步步来解决:

错误原因分析

你用了Bison的C++骨架(%skeleton "lalr1.cc"),并且开启了variant类型的语义值(%define api.value.type variant),这种情况下Bison会生成一个需要接收语义值指针参数的yylex调用逻辑,但你在parser里声明的int yylex();没有参数,同时Flex代码也没适配这个接口,所以编译器就报错“too many arguments to function ‘int yylex()’”了。

解决方案:调整Flex和Parser的接口匹配

我把修改后的完整代码给你,同时解释关键改动点:

1. 修改Flex Lexer代码(lexer.l)

%{
    #include "parser.tab.h"
    // 删掉原来的yylval和STRING枚举,Bison已经帮我们定义好了token类型和语义值类型
%}

%option noyywrap c++ debug
%option prefix="yy"  // 确保和Bison默认的前缀一致,避免命名冲突

// 匹配带引号的字符串,注意转义处理
WORD \"(\\.|\\\n|[^\\\"])*\"

%%

{WORD} {
    // 去掉字符串前后的引号,把内容赋值给Bison的语义值
    std::string raw_str(yytext);
    *yylval = raw_str.substr(1, raw_str.length() - 2);
    return yy::parser::token::STR;
}

// 忽略空白字符(换行、制表符、空格)
[\n\t ] ;

%%

关键改动:

  • 移除了旧的yylval声明和自定义的STRING枚举,改用Bison生成的yy::parser::token::STR
  • 新增了对传入的语义值指针yylval的赋值,把解析到的字符串(去掉引号)传递给Parser

2. 修改Bison Parser代码(parser.ypp)

%{
    #include <iostream>
    // 修正yylex的声明,让它接收Bison语义值的指针参数
    int yylex(yy::parser::semantic_type* yylval);
%}

%skeleton "lalr1.cc"
%require "3.0.2"

%define api.value.type variant
%define api.token.constructor  // 可选,让token的构造更安全
%define parse.error verbose    // 可选,输出更友好的错误信息

%token <std::string> STR
%start program

%%

// 简化规则,直接用$1获取STR的语义值
program : STR {
            std::cout << $1 << std::endl;
        }
         ;

%%

int main()
{
    yy::parser parser;
    return parser.parse();
}

namespace yy
{
    void parser::error(const std::string& m)
    {
        std::cerr << "错误提示:" << m << std::endl;
    }
}

关键改动:

  • 把int yylex();改成int yylex(yy::parser::semantic_type* yylval);,匹配Bison调用时的参数
  • 简化了program规则,原来的STR[a]是较旧的语法,直接用$1就能拿到STR对应的字符串值

编译和测试

按以下命令编译(假设你的文件是lexer.l和parser.ypp):

# 生成Parser的头文件和源文件
bison -d parser.ypp
# 生成Lexer的源文件
flex lexer.l
# 编译链接成可执行文件
g++ -o string_printer parser.tab.cc lex.yy.cc -lfl

运行程序后,输入带引号的字符串比如"Hello Flex & Bison!",回车后就能看到输出:Hello Flex & Bison!

备注:内容来源于stack exchange,提问作者tomdawncats

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 12:49:31