0

我在将字符串存储在野牛的递归规则中时遇到问题。我正在使用 $$ 和一个虚拟变量来保存所有值。在这里,我将报告应该发生的事情和真正发生的事情的清单。

解析器尝试匹配正则表达式,例如“a = b + c”

  • 输入 a = b + c
  • assignement_line 匹配且 buf 变为 "a = b"
  • buf 存储在 $$ 中
  • 一个新的assignement_line,后跟一个TOK_OP(操作的令牌)和TOK_ID(标识符的令牌)匹配(这意味着解析器匹配“+ c”部分)
  • dummy_buf 值为“a = b”,这是问题所在:
    • buf 应该变成 "a = b + c" 而不是变成 "+ c"
    • dummy_buf 值为 "+ c"

如您所见,我丢失了字符串的所有第一部分,我不明白。我正在报告我正在使用的简化规则部分。

lines:
    | lines line
    ;

line: assignement_line
    ;

assignement_line: TOK_IDENTIFIER TOK_EQUAL TOK_IDENTIFIER 
        {
            snprintf(buf, sizeof buf, "%s %s %s", $1, $2, $3);
            $$ = buf;
        }
        |assignement_line TOK_OP TOK_IDENTIFIER
        {
                char *dummy_buf;
            dummy_buf = &buf;
            snprintf(buf, sizeof buf, "%s %s %s", dummy_buf, $2, $3);
            $$ = buf;       
        }                   
    ;
4

1 回答 1

1

如果您的“简化示例”反映了您的实际代码,那么您需要修复您的使用snprintf(并且可能还有其他问题)。

在以下情况下使用确实没有意义dummy_buf

char *dummy_buf;
dummy_buf = &buf;
snprintf(buf, sizeof buf, "%s %s %s", dummy_buf, $2, $3);

这不会复制 in 中的字符串buf,因此您不妨这样写:

snprintf(buf, sizeof buf, "%s %s %s", buf, $2, $3);

但该代码表现出未定义的行为man snprintf以下是使用 GNU libc 的系统上的一小段引述:

一些程序不谨慎地依赖于代码,例如以下

sprintf(buf, "%s some further text", buf);

将文本附加到 buf。但是,标准明确指出,如果在调用 sprintf()、snprintf()、vsprintf() 和 vsnprintf() 时源缓冲区和目标缓冲区重叠,则结果未定义。根据使用的 gcc(1) 版本和使用的编译器选项,上述调用不会产生预期的结果。

于 2013-08-08T16:16:00.123 回答