我怎样才能获得当前flex/lex正在词法分析的行以在yyerror中使用它?

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

我正在使用 flex+bison 作为工具包开发简单的 aql 解析器。现在,我正在尝试在发生语法错误时提供有用的反馈。我想向用户展示这样的想法:

Syntax error:
<line_index>: INSERT { name: "John Doe", 1123: 2, is_working: true } IN users
                                         ^^^^

我已经获得了发生语法错误的信息(行和列),但我真的无法想出获取错误行。我尝试存储全局行缓冲区current_line并在YY_USER_ACTION宏中写入yytext的内容。这样:


  #define YY_USER_ACTION \
      strcpy(current_line+cl_length, yytext); \
      for(int i = 0; yytext[i] != '\0'; i++) { \
          if(yytext[i] == '\n') { \
              memset(current_line, 0, cl_length);
              cl_length = 0;
          } else {
              cl_length++;
          }
      }
}

但是由于使用类似 python 的缩进范围的词法开始条件,我在行首得到了重复的字符。

是否有不同的方法可以使用 Flex 宏或其他方法来做到这一点?

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

Lex 不是面向行的,因此不提供任何有关“行号”等概念的明确帮助。正则表达式运算符 ^,$ 混淆了区别,但您可以使用以下规则轻松处理扫描仪中的行号: \n { my_lineno++; }

这使得像 
yywrap()

这样的东西可以轻松地将多个文件透明地传输到 lex 扫描器:

extern char *files[];
extern int  nfiles;
int yywrap() {
   static int curfile = 0
   static FILE *lastfile = NULL;
   FILE *fp = NULL;
   if (lastfile) {
       fclose(lastfile);
   }
   while (curfile < nfiles && fp == NULL) {
       fp = fopen(files[curfile++], "r");
   }
   yyin = lastfile = fp; 
   return fp == NULL;
}

可能还有其他带有 flex 的方法,它大大增强了 lex。

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