【问题标题】:Why I am getting bad output in this flex file?为什么我在这个 flex 文件中得到错误的输出?
【发布时间】:2022-01-19 11:45:08
【问题描述】:

我正在尝试编写一个允许读取 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 输出。

【问题讨论】:

    标签: c++ linux flex-lexer


    【解决方案1】:

    Flex 可能不是完成这项任务的最佳工具。我建议使用 grep 命令行实用程序。

    Flex 是用于编写解析器的工具;它的目标是将输入拆分为 tokens 序列。它从不搜索模式。在每个输入点,它会尝试所有配置的模式以找到从该点开始的匹配,并选择最长的可能性。然后它执行相关的动作,然后在前进到匹配后的第一个字符后继续。

    如果它在任何点都未能匹配当前输入字符,它使用一个默认规则,其模式匹配任何单个字符,并且其操作是打印该字符。由于您唯一的规则永远不会匹配,因此使用此默认规则一次将整个输入复制到输出一个字符。

    它绝不是面向线的。您可以使用显式模式将输入分成几行,但这些都不会自动发生。

    如果您打算使用 flex,您至少需要了解一点正则表达式*failed* 不是有效的正则表达式;在正则表达式中,* 运算符意味着它后面的事物的零次或多次重复,因此它不能出现在模式的开头。 (*failed* 中的第二个 * 有效,但表示“零个或多个 ds”,这不是您的意思。您可能会将正则表达式与 shell 路径名扩展(“globbing”)混淆,其中 @ 987654327@ 表示“除/ 之外的零个或多个字符”。

    无论如何,*failed* 不是您在该弹性文件中匹配的模式。模式是failed_service,这是一个有效的正则表达式,它匹配自身。您之前定义了相当不必要的宏failed_service,但扩展宏的弹性语法是{macro-name}。如果你设法扩展了那个宏,flex 会报告一个无效的模式。但是,flex 文件中不需要宏。您可以简单地将模式本身放入规则中。

    flex manual 中有对 flex 接受的正则表达式语法的简要描述,但它假定您对这些概念有一些基本的了解。手册还解释了flex文件格式和匹配算法。

    尽管如此,我真的认为您最好通过 grep (例如systemctl | grep -Fw failed)将 systemctl 的输出输出。 Grep 是面向行的,针对此类任务进行了高度优化,并且不需要你想出一套涵盖所有可能性的模式。

    【讨论】:

      猜你喜欢
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2016-11-25
      • 2017-09-18
      • 2012-04-26
      • 2013-10-04
      • 2020-08-30
      相关资源
      最近更新 更多