首页 > 解决方案 > 如何使 c 字符串词法分析器示例工作?

问题描述

以下 f/lex 代码来自其手册。但它不会自行运行。需要一些额外的代码才能使其运行。但我不知道如何添加所需的额外代码。有人可以给我看看吗?谢谢。

%x str
%%
            char string_buf[MAX_STR_CONST];
            char *string_buf_ptr;

\"      string_buf_ptr = string_buf; BEGIN(str);

<str>\" { /* saw closing quote - all done */
        BEGIN(INITIAL);
        *string_buf_ptr = '\0';
        /* return string constant token type and
        * value to parser
        */
}

<str>\n {
/* error - unterminated string constant */
/* generate error message */
}

<str>\\[0-7]{1,3} {
        /* octal escape sequence */
        int result;
        (void) sscanf( yytext + 1, "%o", &result );
        if ( result > 0xff )
        /* error, constant is out-of-bounds */
        *string_buf_ptr++ = result;
}

<str>\\[0-9]+ {
        /* generate error - bad escape sequence; something
        * like '\48' or '\0777777'
        */
}
<str>\\n *string_buf_ptr++ = '\n';
<str>\\t *string_buf_ptr++ = '\t';
<str>\\r *string_buf_ptr++ = '\r';
<str>\\b *string_buf_ptr++ = '\b';
<str>\\f *string_buf_ptr++ = '\f';

<str>\\(.|\n) *string_buf_ptr++ = yytext[1];

<str>[^\\\n\"]+ {
    char *yptr = yytext;
    while ( *yptr ) *string_buf_ptr++ = *yptr++;
}

标签: flex-lexerlex

解决方案


该代码片段中缺少:

  • 如何处理错误条件。

  • 向解析器返回什么标记类型,以及如何表示语义类型。

  • 测试以查看固定长度的内部缓冲区是否已满。

第三个将需要在每次分配后进行测试string_buffer_ptr,这可能会导致错误情况,因此它也可以回到上面的第一点。

基本上,这些完全取决于您的应用程序。您如何处理其他类型的错误?您是尝试恢复并继续解析,还是只写一条错误消息并放弃?您需要将这些错误的处理与其他错误处理保持一致。

最有可能传达结果的代码如下:

   BEGIN(INITIAL);
    *string_buf_ptr = '\0';
    /* return string constant token type and
     * value to parser
     */
    yylval.str = strdup(string_buf);
    return STRING_LITERAL;

但当然,您需要在语义联合str中用正确的标签替换 a char*(假设您使用的是一个),并用return正确的标记名称替换该值。而且您可能更喜欢使用mallocandstrcpy而不是strdup,尽管为了确保您有一个备份定义以备不时之需,还有很多事情strdup需要注意。


推荐阅读