Gnu FLex:yyunput 是如何工作的

Gnu FLex: How does yyunput works

我在理解 flex yyunput 行为时遇到问题。

我想放回一些字符

例如: 我的扫描器发现 CALL{space}{cc}

cc          N?Z|N?C|P[OE]?|M

%%
CALL{blank}{cc}         {BEGIN CON; return yy::ez80asm_parser::make_CALL(loc);}
CALL{mmode}{blank}{cc}  {BEGIN CON; return  yy::ez80asm_parser::make_CALL(loc);}
CALL                    {BEGIN ARG; return  yy::ez80asm_parser::make_CALL(loc);}

我想归还 {cc},以便下次扫描。

yyunput 的两个参数必须是什么?我找不到有关该功能的任何有用信息。

欢迎任何提示 于尔根

您不能 "give back the {cc}" 因为正则表达式没有片段。 (Flex 也不进行捕获,所以用括号括起来也无济于事。)

如果您只想重新扫描令牌的一部分,使用 yylessunput 好得多,因为 yyless 主要只是更改指针。只需调用 yyless 一次,您就可以 return 任意多个字符,因此您只需要知道 return 有多少个字符即可。 (更准确地说,你告诉它你想在 yytext 中保留多少个字符;剩余的字符被 returned 并且 yytext 被相应地截断。)

作为参考,unput 是一个宏,它的单个参数是单个字符,它将被推到未使用的输入的开头,并在其进行时覆盖 yytext。 (在 C++ API 中,它调用内部成员函数 ::yyunput,为其提供额外的必要参数。不要直接调用此函数。)

如果您需要将多个字符压入输入,您需要一次unput一个,从最后一个开始。因为unput破坏了yytext的值,所以在调用unput.

之前需要确保已经复制了unput

对于你的情况,我认为这些都不合适。您可能想要做的是首先不在匹配中包含 {cc} 模式,您可以使用 flex 的尾随上下文运算符 / 来做到这一点。 (假设您不需要在将要 returning 的语义值中包含由 {cc} 匹配的字符;在提供的示例中,yytext 似乎不属于的语义值,因此假设应该是安全的。)为此,您可以这样写:

CALL{mmode}?{blank}/{cc}  {BEGIN CON; return yy::ez80asm_parser::make_CALL(loc);}
CALL                      {BEGIN ARG; return yy::ez80asm_parser::make_CALL(loc);}

(注意:我将您的前两个模式合并为一个模式,因为它们似乎具有相同的操作,但如果您确实需要 {mmode} 匹配的字符,您可能不想这样做。)

如果这不起作用,无论出于何种原因,请使用 yyless。你需要知道你想要 return 输入多少个字符,所以我想你最终会得到这样的东西:

CALL{mmode}?{blank}{cc}  { BEGIN CON;
                           int to_keep = yyleng - 1;
                           switch (yytext[to_keep]) {
                             case 'C': case 'Z':
                               if (yytext[to_keep - 1] == 'N') --to_keep;
                               break;
                             case 'E': case 'O': --to_keep; break
                             case 'P': case 'N': break;
                             default: assert(false); /* internal error */
                           }
                           yyless(to_keep);
                           return yy::ez80asm_parser::make_CALL(loc);
                         }

有关尾随上下文运算符的详细信息,请参阅 Flex manual section on patterns (search for the word "trailing"; there is an important note towards the end as well) as well as the first paragraph of the following chapter on matching. yyless and unput are both documented in the chapter on actions,其中包括它们的用法示例。