【问题标题】:Dynamically turning on and off flex tokens动态打开和关闭弹性令牌
【发布时间】:2019-08-12 17:49:27
【问题描述】:

我有一个程序应该根据命令行参数来调整其输入。所以,要求1/2 的词法为:

NUMBER
SLASH
NUMBER

...当给定一个命令行参数时,词法为:

FREEFORM_TOKEN

...当给定另一个命令行参数时。我使用的工具是flex。

我想知道 flex 是否可以支持这个用例。我的规则是:

[0-9]+(.[0-9]+)?([eE][-+]?[0-9]+)? {
  yylval->d = atof(yytext);
  return NUMBER;
}

[A-Za-z0-9_.]([A-Za-z0-9_./]*[A-Za-z0-9_.])? {
  yylval->s = strdup(yytext);
  return FREEFORM_TOKEN;
}

我可以通过 if 语句简单地动态打开/关闭然后标记,如下所示:

[0-9]+(.[0-9]+)?([eE][-+]?[0-9]+)? {
  yylval->d = atof(yytext);
  return NUMBER;
}

[A-Za-z0-9_.]([A-Za-z0-9_./]*[A-Za-z0-9_.])? {
  if (cmd_line_argument_given)
  {
    yylval->s = strdup(yytext);
    return FREEFORM_TOKEN;
  }
}

...或者 .l 文件中的长正则表达式是否存在一些问题,这会导致 1/2 匹配但不返回任何内容?

在实践中我应该如何实现这个要求?

我应该这样做吗:

<INITIAL,CMDOPT>[0-9]+(.[0-9]+)?([eE][-+]?[0-9]+)? {
  yylval->d = atof(yytext);
  return NUMBER;
}

<CMDOPT>[A-Za-z0-9_.]([A-Za-z0-9_./]*[A-Za-z0-9_.])? {
  yylval->s = strdup(yytext);
  return FREEFORM_TOKEN;
}

...如果我想打开FREEFORM_TOKEN,然后执行BEGIN(CMDOPT),如果我想关闭FREEFORM_TOKEN,就让它保持INITIAL 状态?那么所有规则都将具有INITIALCMDOPT 状态,但FREEFORM_TOKEN 除外,它只有CMDOPT 状态。

【问题讨论】:

    标签: c flex-lexer lex


    【解决方案1】:

    我想知道 flex 是否可以支持这个用例。

    是的,以各种方式。

    我可以通过 if 语句简单地动态打开/关闭然后标记,如下所示:

    不,这不是(完全)其中一种方式。如果您只是将是否采取任何操作设为条件,那么当 no 采取任何操作时,令牌将被静默消耗,而不是与不同的规则匹配。

    在这种情况下,要让 flex 回退到不同的规则,您可以使用the REJECT() directive。这指示 flex 改为应用与输入(或其前缀)匹配的次优规则。

    请注意,REJECT 出现在您的扫描仪定义中会使整个扫描仪显着变慢。这是您可以为扫描仪性能做的最糟糕的事情。但在实践中这对你来说可能不是问题。

    在实践中我应该如何实现这个要求?

    我应该[使用start conditions]代替[?]

    开始条件通常是在不同规则子集中进行选择的更好选择。正如@Cheatah 首先观察到的,您可以在扫描开始之前使用yy_push_state() 适当地设置开始条件。这是我的建议。

    如果你确实使用了开始条件,那么你可以通过使用其中的两个来简化你的规则,一个用于每个语法选项,并使它们包含。那么所有你没有用任何开始条件标记的规则都将适用于两者,你只需要标记那些特定于一个或另一个开始条件的规则。

    【讨论】:

      【解决方案2】:

      我认为您可能应该使用开始条件。然后当你启动你的软件时,在你真正开始词法分析之前,使用yy_push_state(YOUR_STATE)切换到不同的启动条件。​​

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 2021-12-12
        • 2019-09-03
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        相关资源
        最近更新 更多