C宏可以在flex中扩展吗?

问题描述 投票:0回答:1

据我所知,以下内容在 Flex 中不起作用:

...
std::string opt_val = "--help";

%%
opt_val { /* do something */ }
%%

我可以扩展 C 宏吗? 我试过这个:

%{
#define MCR_OPTION "--help"
%}

ALIAS_OPTION MCR_OPTION

%%
{ALIAS_OPTION} { /* do something */ }
%%

不幸的是,这似乎不起作用。 我想将字符串文字值保留在扫描器规则部分之外的其他位置, 这样如果它们发生变化,我就会少一个地方更新。 我错过了一些明显的东西吗?

(编辑):这是我测试过的更完整的示例:

测试.l

%option noyywrap

%{
#include <iostream>
#define MCR_HELP_OPT "--help"
#define MCR_HELP_OPT2 --help
%}

ALIAS_HELP_OPT MCR_HELP_OPT
ALIAS_HELP_OPT2 MCR_HELP_OPT2

%%
"--works" { std::cout << "this works" << std::endl; }
{ALIAS_HELP_OPT} { std::cout << "help" << std::endl; }
{ALIAS_HELP_OPT2} { std::cout << "help2" << std::endl; }
\n { return 0; }
. { /* consume */ }
%%

int main(int, char**) {
    while (yylex()) {}
}

我是这样测试的:

> flex test.l && c++ lex.yy.c
> echo "--help" | ./a.out
> echo "--works" | ./a.out
this works
c macros flex-lexer
1个回答
0
投票

最终我决定使用CMake的configure_file功能; 这是一个最小的工作示例:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.25)
project(test)

find_package(FLEX REQUIRED)

set(SCANNER_FLEX ${CMAKE_BINARY_DIR}/test.l)
set(SCANNER_SRC ${CMAKE_BINARY_DIR}/test.cpp)
set(MCR_HELP_OPT "--help")

configure_file(test.l.in ${SCANNER_FLEX} @ONLY)

FLEX_TARGET(scanner ${SCANNER_FLEX} ${SCANNER_SRC})
add_executable(run ${SCANNER_SRC})

target_include_directories(run PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}
)

测试.hpp

#define MCR_HELP_OPT "--help"

测试.l.in

%option noyywrap

%{
#include <iostream>
#include "test.hpp"
%}

%%
@MCR_HELP_OPT@ { std::cout << "help" << std::endl; }
\n { return 0; }
. { /* consume */ }
%%

int main(int, char**) {
    while (yylex()) {}
}

然后构建并运行它:

> cmake -B build
> make -C build
> echo "--help" | ./build/run
help
© www.soinside.com 2019 - 2024. All rights reserved.