提问人:Dazckel 提问时间:12/16/2021 最后编辑:Adrian MoleDazckel 更新时间:12/23/2021 访问量:72
为什么我在这个 flex 文件中得到错误的输出?
Why I am getting bad output in this flex file?
问:
我正在尝试编写一个允许读取 systemctl 输出的 Flex 文件。 这个想法是只显示那些无法启动的服务。 我的代码是:
%{
#include <iostream>
#include <fstream>
using namespace std;
ifstream file;
char* service_name;
int nfs=0;
%}
failed_service *failed*
%%
failed_service {nfs++;cout << yytext << endl;}
%%
int main()
{
system("systemctl > /var/tmp/system_start.txt");
file.open("/var/tmp/system_start.txt");
yyFlexLexer strm (&file,0);
strm.yylex();
}
你能告诉我我失败的地方吗?
输出显示整个 systemctl 输出。
答:
Flex 可能不是完成此任务的最佳工具。我建议使用 grep 命令行实用程序。
Flex 是用于编写解析器的工具;其目标是将输入拆分为一系列令牌。它从不搜索模式。在每个输入点,它都会尝试所有配置的模式,以查找从该点开始的匹配项,并选择最长的可能性。然后,它执行关联的动作,然后在晋级到匹配后的第一个角色后继续。
如果它未能与当前输入字符匹配,它将使用默认规则,其模式与任何单个字符匹配,并且其操作是打印字符。由于唯一的规则从不匹配,因此使用此默认规则将整个输入一次复制到一个字符的输出中。
它绝不是面向线的。您可以使用显式模式将输入拆分为行,但这一切都不会自动发生。
如果你打算使用 flex,你至少需要学习一点关于正则表达式的知识。 不是有效的正则表达式;在正则表达式中,运算符表示它所遵循的事物的零次或多次重复,因此它不能出现在模式的开头。(第二个 in 是有效的,但表示“零个或多个 s”,这不是你的意思。您可能会将正则表达式与 shell 路径名扩展(“通配”)混淆,其中 a 表示“除 ' 以外的零个或多个字符”。*failed*
*
*
*failed*
d
*
/
在任何情况下,都不是您在该 flex 文件中匹配的模式。模式是 ,这是一个有效的正则表达式,它与自身匹配。您之前定义了相当不必要的宏,但用于扩展宏的 flex 语法是 。如果您设法扩展了该宏,flex 将报告无效模式。但是,flex 文件中不需要宏;您可以简单地将模式本身放在规则中。*failed*
failed_service
failed_service
{macro-name}
在 flex 手册中,对 flex 接受的正则表达式的语法进行了简要描述,但它假定您对这些概念有一些基本的熟悉。该手册还解释了 flex 文件格式和匹配算法。
尽管如此,我真的认为您最好通过 grep (例如)传输 systemctl 的输出。Grep 是面向线的,针对此类任务进行了高度优化,并且不需要您提出一组涵盖所有可能性的模式。systemctl | grep -Fw failed
下一个:OpenGL 改变法线
评论