0

我想将 flex 与字符串缓冲区一起使用,而不是默认的标准输入,所以我使用yy_scan_string. 除了“以结尾”模式外,它几乎可以正常工作。

例如

%%
ab$  {//do something}
%%

ab$意味着匹配“ab”,如果它恰好是结束字符串,使用标准输入作为输入,它可以工作,但如果它是yy_scan_string,它不是。

测试:

%option noyywrap

%{
#include <stdio.h>
%}

%%
ab$    { printf("match ab$\n"); }
%%

int main(int argc, char ** argv)
{
    if (argc > 1)
        yy_scan_string(argv[1]);

    yylex();

    if (argc > 1)
        yylex_destroy();
}

然后使用flex test.l; gcc lex.yy.c;if using echo ab | ./a.out,它打印match ab$,并且工作正常,但如果 using ./a.out ab,它只打印 input ab,不匹配该ab$规则。

4

1 回答 1

0

我很惊讶这个问题一直没有得到解答,因为它是一个非常简单的问题,在手册中有介绍。如果您查看有关模式的手册部分,它会解释$模式的工作原理:

'r$' 和 'r',但仅在行尾(即,就在换行符之前)。相当于'r/\n'。

请注意,flex 的“换行符”概念正是用于编译 flex 的 C 编译器将 '\n' 解释为的任何内容;特别是,在某些 DOS 系统上,您必须自己过滤掉输入中的 '\r',或者显式使用 'r/\r\n' 作为 'r$'。

所以你可以看到手册明确说'$'不等于ends-with. 它并不是您可能在 SNOBOL 中找到的真正正确的弦锚。

为了让您的程序将命令行参数与 shell 输入相同,您需要添加代码来模拟操作系统在执行echo ab |. 这些将是\n并且EOTTheEOT与 flex 不匹配,并且实际上并没有标记文件结束,但我在我的仿真中是一个书呆子。

%option noyywrap

%{
#include <stdio.h>
%}

%%
ab$    { printf("match ab$\n"); }
%%

int main(int argc, char ** argv)
{   char  * buffer;
    if (argc > 1) {
        int length = strlen(argv[1]);
        buffer = (char *)malloc(length+3);
        strncpy(buffer,argv[1],length);
        buffer[length] = '\n';
        buffer[length+1] = 4; /* EOT or Cntrl-D representing EOF on unix */
        buffer[length+2] = 0;
        yy_scan_string(buffer);
       }
    yylex();

    if (argc > 1)
        yylex_destroy();
}
于 2015-04-22T19:48:10.847 回答