c - 动态打开和关闭 flex token

标签 c flex-lexer lex

我有一个程序应该根据命令行参数对输入进行词法分析。因此,要求是 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;
}

...然后执行 BEGIN(CMDOPT) 如果我想打开 FREEFORM_TOKEN 并且将其保留在 INITIAL 状态,如果我想关闭 FREEFORM_TOKEN?然后所有规则都将具有 INITIALCMDOPT 状态,但 FREEFORM_TOKEN 除外,它只有 CMDOPT 状态。

最佳答案

I'm wondering whether flex can support this use case.

是的,以各种方式。

Can I simply dynamically turn on/off then token by an if statement, like this:

不,那不是(完全)其中一种方法。如果您只是将是否采取任何行 Action 为条件,那么当没有采取行动时, token 将被静默消耗,而不是根据不同的规则进行匹配。

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

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

How in practice should I implement this requirement?

Should I [use start conditions] instead [?]

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

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

关于c - 动态打开和关闭 flex token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57465900/

相关文章:

c - 返回 C 中正因子计数的方法

从用户空间调用驱动程序 API 的成本

C 仅导出所需符号(不编辑原始文件)

parsing - YACC| Bison :How do I manipulate parse tree?

Python C API : Call a Python function with argument(s) passed by reference

c - 如何添加不断询问用户输入并将所有输入保存到文件

bison - BNF 到 Flex/Bison

c++ - Flex 词法分析器输出修改

C with Bison+Flex 检查规则文件

parsing - Verilog 门级解析器