gpt4 book ai didi

c - $1 在 yacc 中意味着什么,我怎样才能得到它的值

转载 作者:行者123 更新时间:2023-11-30 14:38:19 25 4
gpt4 key购买 nike

我想完成一个关于varlist声明的解析,就像 varlist:id 逗号 varlist|id。这时候我需要设置一个关于var的列表。所以我写了这段代码:

varlist: id comma varlist{ createtnode($1.idcontext);}
|id{createtnode($1.idcontext);};

但我发现 $1.idcontext 不是我想要的 idcontext,它应该是此 id token 的 idcontext。

现在,$1.idcontext就是这句话“varlist”。如果没有代码操作,此语法可以正常工作。

typedef struct{
int* TC;
int* FC;
}boolcode;
typedef struct {
char* idcontext;
int constvalue;
int chain;
boolcode ftentry;
}includes;

/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef struct{
int classify;
includes unique;
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif

VARList: IDENcode COMMA VARList{
if(YYDEBUG)
{printf("6\n");
printf("%s\n",$1.idcontext);
}
varlistnode* newvar=malloc(sizeof(varlistnode));
newvar->varname=$1.idcontext;
newvar->value=0;
newvar->next=NULL;
mynotes->next=newvar;
mynotes=mynotes->next;
}|IDENcode{
if(YYDEBUG)
{printf("7\n");printf("%s\n",$1.idcontext);}
varlistnode* newvar=malloc(sizeof(varlistnode));
newvar->varname=$1.idcontext;
newvar->value=0;
newvar->next=NULL;
mynotes->next=newvar;
mynotes=mynotes->next;
};

等待识别的单词:

a,b,c,d

printf()函数的结果:

7
d:
6
c,d:
6
b,c,d:
6
a,b,c,d:enter code here

最佳答案

这个程序中的真正问题在这个问题中是不可见的,因为错误存在于你的词法扫描器中。

您没有在问题中包含 Flex 文件,但有理由猜测它包含如下内容:

[[:alpha:]_][[:alnum:]_]*  { yylval.unique.idcontext = yytext;  /* INCORRECT */
return IDENcode;
}

应该是这样的

[[:alpha:]_][[:alnum:]_]*  { yylval.unique.idcontext = strdup(yytext);
return IDENcode;
}

yytext 指向扫描仪的内部缓冲区,每次调用扫描仪时都会修改其内容。您所看到的是这个问题的温和版本,因为您的输入非常短;如果输入足够长,yylex 需要从输入文件重新填充缓冲区,那么您将在 idcontext 字段中看到完整的垃圾。如果您想稍后使用该字符串,则需要复制它(然后您需要记住当您不再需要它时free()该副本,这可能有点麻烦一个挑战。)

<小时/>

另一个可能的问题 - 老实说,我不知道你是否认为这是一个问题,因为你没有指定你期望从调试跟踪中得到什么输出 - 是你的右递归规则:

varlist: id comma varlist  { createtnode($1.idcontext); }
| id { createtnode($1.idcontext); }

最终以相反的顺序在 id 上调用 createtnode,因为当规则匹配时会执行 Bison 缩减操作。像这样使用右递归意味着要执行的第一个 varlist 操作实际上是与最后一个 id 对应的操作。

如果您希望操作从左到右执行,则需要使用左递归:

varlist: varlist comma id  { createtnode($3.idcontext); } /* See below */
| id { createtnode($1.idcontext); }

左递归还有其他优点。例如,它不需要所有id(和逗号)堆积在解析器的内部堆栈上等待最终的归约操作。

同样,您没有显示足够的代码来了解如何使用这些操作的结果。在我看来,您正在尝试创建一个全局变量链接列表,其 header 存储在全局变量中。 (mynotes 显然指向列表的尾部,因此它不能用于恢复头部。)如果是这种情况,那么上面的更改应该可以正常工作。但将 varlist 的语义值设为列表头会更正常,从而避免使用全局变量。这将导致代码看起来更像这样:

varlist: id comma varlist  { $$ = append($1, createtnode($3.idcontext)); }
| id { $$ = append(newlist(), createtnode($1.idcontext); }

关于c - $1 在 yacc 中意味着什么,我怎样才能得到它的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56699785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com