flex lexer:yytext更改后应该更新哪个变量?

时间:2019-04-10 16:21:15

标签: flex-lexer

我正在尝试编写一个简单的编译器。我目前在扫描仪部分。 关于字符串标记,flex文件中有以下规则:

\"([^\\\n]|\\.)*\" { clean_string(); return TK_STRING; }

它运行完美(这不是问题)。调用clean_string函数以删除“前导和尾随”,并将\ n和\ t转换为其相应的ascii字符。

int clean_string () {
  char * mystr;

  mystr=strdup(yytext+1) ; // copy yytext and remove leading "
  if (! mystr) return 1;
  mystr[yyleng-2]='\0'; // remove trailing "
  for (int i=0, j=0; i<=strlen(mystr); i++, j++) { // "<=" and not "<" to get /0, i : mystr indice and j : yytext indice
    if (mystr[i]=='\\') {
      i++;
      if (mystr[i]=='n')        yytext[j]='\n';
      else if (mystr[i]=='t')   yytext[j]='\t';
      else yytext[j]=mystr[i];
    }
    else yytext[j]=mystr[i];
  }
  yyleng=strlen(yytext);
  free(mystr);
  return 0 ;
}

它也完美地工作。

我的问题如下:
在函数的最后,我更新了yyleng,因为yytext已更改。我想知道是否还有另一个变量要更新,以避免程序另一部分出现意外行为。

1 个答案:

答案 0 :(得分:1)

除非您在操作中使用yymore()(并且显然没有这样做),否则由Flex生成的扫描仪不需要yyleng来反映yytext的长度。您可以通过任何方式修改yyleng,也可以在索引0和索引yytext之间修改yyleng-1的内容,包括使其更短。

话虽如此,您需要了解yytext的内容仅在下次调用yylex之前是稳定的。在几乎所有应用程序中,尤其是如果您打算从具有超前性的解析器(例如yacc / bison生成的解析器)中使用扫描仪,您将希望扫描仪使用内容的 copy yytext中的。特别是,由yacc / bison生成的扫描程序期望在联合体yylval的某个成员中找到标记的语义值(即,标记字符串或从中得出的某些值),通常以指针的形式。

因此,我强烈建议您的函数将所需的字符串内容放入mystr中,然后将其返回(而不是立即释放它),并且该操作将指针放置在解析器可以使用的位置它。只需对您的代码进行少量修改,即可使扫描器与yacc / bison生成的解析器一起使用。