Lor*_*rin 1 c++ g++ flex-lexer
这是 .lex 文件的片段:
    /* 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 的内容附加到最后一个。在部分中使用ECHO; yymore();组合<title>.+显示整个文本。然而,删除 ECHO 并使用cout会导致yymore()损坏。未附加文本。
此外,我无法获取<title>^[\n]{1}部分中的标题文本。我得到的一切都只是“\n”。
我做错了什么?
这并不是对 的准确描述yymore。yymore将导致下一个标记yytext包含当前的yytext. (之前的文本已经消失了;它无法恢复——当然,除非它被标记为通过调用来保存yymore())。
我不明白你期望这个开始条件做什么。
据称终止启动条件的模式是:
<title>^[\n]{1}
锚^定模式,因此它仅在换行符之后匹配。(它是一个零长度谓词,就像在标准 Posix 正则表达式中一样。)但是起始条件中的模式不可能title满足^匹配,因为在该状态下匹配的任何模式都不能匹配以换行符结尾的字符串(.不匹配换行符,并且#[\t ]规则显然以空格或制表符结尾。)
另外,{1}是完全多余的(它意味着“恰好一次重复”,这是一种恒等变换)并且[\n]与 没有什么不同\n,所以你可以直接写:
<title>^\n
我的猜测是您没有指定%option nodefault,因此您让默认匹配默默地回显而不显示错误消息。问题在于,yymore()由于显而易见的原因,标准默认匹配规则不会调用 ,因此在执行默认操作时,累积的匹配会丢失。
还要注意ECHO回声yytext;如果您使用yymore(或yyless),那么这与“此规则匹配的文本块”不同。考虑以下简单的弹性程序:
%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