Parsing 在递归规则中保存bison中的值

Parsing 在递归规则中保存bison中的值,parsing,recursion,bison,string-concatenation,Parsing,Recursion,Bison,String Concatenation,我在bison中的递归规则中存储字符串时遇到了一个问题。 我使用$$和一个虚拟变量来保存所有值。 在这里,我将报告一份清单,列出应该发生的事情,以及 到底发生了什么 解析器尝试匹配正则表达式,例如“a=b+c” 输入a=b+c 赋值_行匹配,buf变为“a=b” buf存储在$$ 匹配一个新的赋值_行,后跟一个TOK_OP(操作的令牌)和TOK_ID(标识符的令牌)(这意味着解析器匹配“+c”部分) 虚拟值为“a=b” 问题是: buf应该变成“a=b+c”,而不是变成“+c” 虚拟值为“+

我在bison中的递归规则中存储字符串时遇到了一个问题。 我使用$$和一个虚拟变量来保存所有值。 在这里,我将报告一份清单,列出应该发生的事情,以及 到底发生了什么

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

  • 输入a=b+c
  • 赋值_行匹配,buf变为“a=b”
  • buf存储在$$
  • 匹配一个新的赋值_行,后跟一个TOK_OP(操作的令牌)和TOK_ID(标识符的令牌)(这意味着解析器匹配“+c”部分)
  • 虚拟值为“a=b” 问题是:
    • buf应该变成“a=b+c”,而不是变成“+c”
    • 虚拟值为“+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;       
        }                   
    ;
如果您的“简化示例”反映了您的实际代码,那么您需要修复使用
snprintf
(可能还有其他问题)

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

char *dummy_buf;
dummy_buf = &buf;
snprintf(buf, sizeof buf, "%s %s %s", dummy_buf, $2, $3);
这不会复制
buf
中的字符串,因此您不妨编写:

snprintf(buf, sizeof buf, "%s %s %s", buf, $2, $3);
但该代码表现出未定义的行为。下面是使用GNU libc的系统上的
mansnprintf
的一段小引语:

有些程序轻率地依赖如下代码

sprintf(buf,“%s一些进一步的文本”,buf)

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


非常感谢你的回答!我以这种方式使用sprintf(),因为我遵循了一个教程。现在我用strcat()链更改了snprintf部分,代码运行良好。我原以为问题出在野牛语法规则上(因为我是新手),但我错了!