flex-lexer - flex lexer:在 yytext 更改后我应该更新哪个变量?
问题描述
我正在尝试编写一个简单的编译器。我目前在扫描仪部分。关于字符串标记,我在 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 已更改。我想知道我是否有另一个变量要更新,以避免程序的另一部分出现一些意外行为。
解决方案
除非您yymore()
在您的操作中使用(显然,您不使用),否则 flex 生成的扫描仪不需要yyleng
反映yytext
. 您可以yyleng
以任何方式修改,也可以修改yytext
index 0 和 index 之间的内容yyleng-1
,包括使其更短。
话虽如此,您需要注意 的内容yytext
只有在您下次调用时才会稳定yylex
。在几乎所有应用程序中,特别是如果您计划使用具有前瞻功能的解析器(例如由 yacc/bison 生成的解析器)使用扫描仪,您将希望扫描仪使用yytext
. 特别是,yacc/bison 生成的扫描器期望在 union 的某个成员中找到标记的语义值(即标记字符串或从它派生的某个值)yylval
,通常以指针的形式。
所以我强烈建议您的函数将所需的字符串内容放入 mystr
然后返回它(而不是立即释放它),并且该操作将指针放在解析器可以使用它的位置。这将只需要对您的代码进行少量修改,并使扫描仪可以与 yacc/bison 生成的解析器一起使用。
推荐阅读
- audio - Flutter - 如何播放环境声音?
- ruby-on-rails - 不允许的参数 & 无法显示嵌套的 fields_for
- html - 仅从 webelemnt 获取内部文本
- react-native - 在 TouchableOpacity 上创建“凸起”或阴影效果:React Native
- php - 在 write() fpdf 中回显数据库
- selenium - '拒绝连接!selenium 服务器是否已启动?\n' 同时针对 Selenium Grid 运行 Nightwatch.js 测试
- java - 带括号语法的 Java 函数定义
- javascript - Angular Typescript 在 Switch 语句的视图中显示变量
- django - Django URL 标记:在模型 id 上获取 NoReverseMatch,即使它存在
- javascript - Rails j Query section_tag当前值未重置为默认值