【问题标题】:Flex: use of yymore()Flex:使用 yymore()
【发布时间】:2015-02-01 19:41:17
【问题描述】:

这是来自 .lex 文件的 sn-p:

    /* Empty line just with the newline character signs end of
       the title block 
     */
<title>^[\n]{1} {
    yymore(); ECHO;
    // std::cout << "Text: " << yytext << std::endl;

    // ... do something with yytext

    BEGIN(INITIAL);

}

    /* Reads everything up to the end of line. */
<title>.+ {
    ECHO; yymore();
    //std::cout << "yymore: " << yytext << std::endl;
}

    /* Every title starts with # and text follows. */
#[\t\ ] {

    // ... prepare for html output

    BEGIN(title);
}

目标是阅读“#”之后的整个文本。根据在线教程,yymore() 应该将当前 yytext 的内容附加到最后一个。在&lt;title&gt;.+ 部分中使用ECHO; yymore(); 组合可显示整个文本。但是删除 ECHO 并使用 cout 会使 yymore() 损坏。不附加文本。

此外,我无法在&lt;title&gt;^[\n]{1} 部分中获取标题文本。我得到的只是“\n”。

我做错了什么?

【问题讨论】:

    标签: c++ g++ flex-lexer


    【解决方案1】:

    这不是对yymore 的准确描述。 yymore 将导致 next 令牌的 yytext 包含当前的 yytext。 (之前的文本已经消失了;它无法恢复——当然,除非它被标记为通过调用 yymore() 来保存)。

    我不明白你期望这个启动条件做什么。

    假定终止开始条件的模式是:

    <title>^[\n]{1}
    

    ^ 锚定了模式,因此它只会在换行符之后匹配。 (它是一个长度为零的谓词,就像在标准 Posix 正则表达式中一样。)但是开始条件 title 中的模式不可能满足 ^ 匹配,因为在该状态下匹配的任何模式都不能匹配以换行符(. 与换行符不匹配,#[\t ] 规则显然以空格或制表符结尾。)

    另外,{1} 是完全多余的(它的意思是“完全重复”,这是一个恒等变换),[\n]\n 没有什么不同,所以你可以写:

    <title>^\n
    

    我的猜测是你没有指定%option nodefault,所以你让默认匹配静默回显,没有错误消息。问题是标准的默认匹配规则没有调用yymore(),原因很明显,所以在执行默认操作时,累积的匹配丢失了。

    还要注意ECHOyytext 相呼应;如果您使用yymore(或yyless),则与“此规则匹配的文本块”不同。考虑以下简单的 flex 程序:

    %option noyywrap noinput nounput nodefault
    %%
    .    { yymore(); ECHO; putchar('\n'); }
    \n
    

    示例运行:

    $ flex -o tri.c tri.l
    $ gcc -Wall -o tri tri.c -lfl
    $ ./tri <<<0123456789
    0
    01
    012
    0123
    01234
    012345
    0123456
    01234567
    012345678
    0123456789
    

    【讨论】:

      猜你喜欢
      • 2014-04-26
      • 2020-01-04
      • 1970-01-01
      • 2017-08-14
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      相关资源
      最近更新 更多