我有一个程序,它应该根据命令行参数来调整其输入。因此,要求将1/2定义为:
NUMBER
SLASH
NUMBER...when给出了一个命令行参数,并将其拼写为:
FREEFORM_TOKEN...when给出了另一个命令行参数。我使用的工具是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;
}
}...or在.l文件中有长的regexp是否存在问题,这会导致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;
}...and,如果我想打开FREEFORM_TOKEN,如果我想关闭FREEFORM_TOKEN,只需将它保持在INITIAL状态,就执行BEGIN(CMDOPT)操作吗?那么所有规则都有INITIAL和CMDOPT状态,只有FREEFORM_TOKEN除外,后者只有CMDOPT状态。
发布于 2019-08-12 19:37:41
我想知道flex是否能支持这个用例。
是的,在不同的方面。
我可以简单地通过if语句动态地打开/关闭令牌,如下所示:
不,这不是(完全)一种方式。如果您只是将是否采取任何操作作为条件,那么当不采取任何操作时,令牌将被静默地消耗,而不是与另一条规则相匹配。
相反,在这种情况下,要使flex回到另一条规则,您可以使用指令。这将指示flex应用与输入(或其前缀)匹配的次优规则。
请注意,在扫描仪定义中出现的REJECT会使整个扫描仪的运行速度大大减慢。这是对扫描仪性能来说最糟糕的一件事。但在实践中这对你来说可能不是问题。
在实践中,我应该如何实现这一要求? 我应该用起动条件代替吗?
启动条件通常是在不同规则子集中进行选择的较好选择。正如@Cheatah首先观察到的,您可以在开始扫描之前使用yy_push_state()适当地设置开始条件。这将是我的建议。
如果您确实使用了开始条件,那么您可以通过使用其中的两个规则(每个语法选项都使用一个),并使它们具有包容性,从而使规则变得更简单。然后,所有不使用任何开始条件标记的规则都将适用于这两个条件,并且只需要标记特定于一个启动条件或另一个启动条件的规则。
发布于 2019-08-12 19:32:19
我认为你应该使用一个开始的条件。然后,在启动软件时,在实际开始词法分析之前,使用yy_push_state(YOUR_STATE)切换到不同的启动条件。
https://stackoverflow.com/questions/57465900
复制相似问题