gpt4 book ai didi

c - 在 yacc/bison 之外使用 lex/flex

转载 作者:行者123 更新时间:2023-11-30 17:12:15 24 4
gpt4 key购买 nike

我目前正在使用 bison 和 flex 来解析线性时序逻辑公式并从中生成自动机。我以“默认”方式使用 flex,即如有必要,将 token 写入 yylval 并返回 bison token 标识符。

我正在使用单独的例程来扫描输入文件。输入由标识符名称和整数/实数组成,flex 已经可以处理这两者。示例:

x    y
3.20 78.3
3.31 76.2
3.32 77.4
//etc

我的问题是:如果可能的话,我将如何利用flex来扫描输入文件?我知道如何切换 Flex 的输入缓冲区,但之后如何获取 token 值?如果解决方案比单独的例程更复杂,那么我就不会费心去做。

顺便说一句,我正在使用 C,但将来我需要最终将其移植到 C++。

谢谢。

最佳答案

如果问题像您的示例所示那么简单,您可以只使用 fscanffscanf 的问题可能与使用 Flex 生成的扫描器的问题没有什么不同,即换行符被简单地视为空格。如果您的扫描仪返回换行符的特殊标记(或者可以说服这样做,请参见下文),请继续阅读。

如果我正确理解您想要做什么,您只需正确设置输入,然后重复调用yylex。如果您使用默认的不可重入 API,那么它可能看起来像这样:

// Returns a count, and sets the out parameter to a
// malloc'd array of malloc'd strings.
// The free function is left as an exercise.
int read_headers(char*** out) {
int count = 0;
char** id_array = NULL;
*out = id_array;
int token;
while ((token = yylex()) == TOKEN_IDENTIFIER) {
id_array = realloc(id_array, (count + 1) * sizeof *id_array);
if (id_array) *out = id_array;
else
// Handle error
id_array[count ++] = strdup(yytext);
}
if (token != '\n')
// Handle error
return count;
}

// Reads exactly n numbers and stores them in the out parameter,
// which must point at an array of size n.
// Returns: n on success. 0 if EOF reached. -1 on error
int read_n_numbers(double* out, int n) {
for (int i = 0; i < n; ++i, ++out) {
int token = yylex();
if (token != TOKEN_NUMBER) {
if (i == 0 && token == 0) return 0;
// Error: non-number or too few numbers
return -1;
}
*out = yylval.number;
}
if (yylex() != '\n') {
// Error: too many numbers
return -1;
}
return 0;
}

您的扫描仪可能实际上并未返回换行符的 \n。这在表达式语法中很少有用(尽管有时有用)。但修改扫描器以根据需要处理换行符是很容易的;您只需要使用开始条件即可。我们将其设为包含启动条件,因为它只需要处理换行符,但请注意,这意味着所有未标记的规则也都处于事件状态,因此您需要确保处理换行符的未标记规则也只处理单个换行符。

%s RETURN_NEWLINES
%%
<RETURN_NEWLINES>\n { return '\n'; }
\n ; // Ignore a single newline
[ \t]+ ; // Ignore any number of horizontal whitespace

完成后,您只需在扫描之前调用 BEGIN(RETURN_NEWLINES) 即可启用换行符(并且 BEGIN(INITIAL) 返回忽略它们。)您需要在 Flex 定义文件中放置启用和禁用换行扫描的函数,因为所需的宏不会导出。

关于c - 在 yacc/bison 之外使用 lex/flex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31668237/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com