函数声明的生产规则中yytext中的意外值

问题描述 投票:0回答:1

我正在编写带有flex和bison的编译器以进行大学作业。我在向符号表添加函数标识符时遇到了麻烦-在评估函数声明时,我在yytext中得到了期望的标识符的括号。在我的flex文件中,其中yylval是一个联合,vlexstruct

abc         [A-Za-z_]
alphanum    [A-Za-z_0-9]
id          {abc}+{alphanum}*

...

#define STORE_YYLVAL_NONE\
  do{\
    ... // location control irrelevant to the problem
    yylval.vlex.type = none_t;\
    yylval.vlex.value.sValue = yytext;\
  }while(0)

...

{id} {
  LOG_DEBUG("id: %s\n", yytext);
  STORE_YYLVAL_NONE;
  return TK_IDENTIFIER;
}

[,;:()\[\]\{\}\+\-\*/<>!&=%#\^\.\|\?\$] {
  LOG_DEBUG("special\n");
  STORE_YYLVAL_NONE;
  return *yytext;
}

...

而且在我的野牛文件中,我有:

new_identifier_with_node: TK_IDENTIFIER {
  hshsym_add_or_exit(&hshsym, yylval.vlex.value.sValue, &(yylval.vlex));
  $$ = ast_node_create(&(yylval.vlex));
};

func: type new_identifier_with_node '(' param_list ')' func_block { ... };

我在hshsym_add_or_exit中也有一个日志,它将一个标识符添加到我的符号表中。解析以下程序时:

int k(int x,int y, int z){}
int f(){
        k(10,20,30);
}

我得到以下调试输出:

yylex: DEBUG! id: k
yylex: DEBUG! special
hshsym_add_or_exit: DEBUG! Declaring: (

即,当评估new_identifier_with_node生产时,yytext的内容是(,而不是k,正如我所期望的那样。代码是否高于原因?我仍然有一些尚未解决的转移/减少冲突,我认为这可能是错误的,但是我看不出在这种特定情况下的情况。我相信我缺少真正基本的东西,但是我看不到。这时该项目很大(可耻地混乱了),但是如果需要,我可以提供一个完整且可复制的示例。

c compiler-construction bison flex-lexer
1个回答
0
投票

基本问题是您正在yylval生产中使用new_identifier_with_node,而不是$1$1是生产中第一个符号的语义值,在这种情况下为TK_IDENTIFIER

在野牛动作中,yylval通常是超前标记的值,即输入流中的next标记。这就是在这种情况下它显示为括号的原因。但是您通常不能指望这一点,因为野牛会在读取先行标记之前执行默认还原。通常,除错误恢复中的某些应用程序外,在野牛操作中使用yylval很少有用。

即使在解决此问题之后,您仍会发现语义值不正确,因为您的flex操作正在将指针转发到内部数据缓冲区,而不是复制令牌字符串。参见,例如,this question

© www.soinside.com 2019 - 2024. All rights reserved.