bison - flex 究竟是如何支持 Bison 定位的?

标签 bison flex-lexer

我正在尝试使用 flex 和 bison 创建过滤器,因为我想从复杂的语言中获取某些语法元素。我的计划是使用 flex + bison 来识别语法,并转储出感兴趣元素的位置。 (然后使用脚本根据转储的位置获取文本。)

我发现 flex 可以支持名为 bison-locations 的 Bison 功能,但它是如何工作的。我尝试了 flex 文档中的示例,似乎 yylloc 不是由 flex 自动设置的,我总是得到 (1,0)-(1,0) . flex 可以自动计算每个 token 的位置吗?如果没有,定义了哪些接口(interface)函数供我实现?有什么例子吗?

关于工具有更好的解决方案吗?

最好的祝福,
凯文

编辑:

现在yylex的界面变成了:

int yylex(YYSTYPE * yylval_param,YYLTYPE * yylloc_param );

Bison 手册未指定词法分析器应如何实现以正确设置 yylloc_param。对我来说,很难手动跟踪每个 token 的列号。

最佳答案

yylex 声明可能更改了,因为您使用了可重入或纯解析器。似乎网络上的许多文档都表明,如果您希望 Bison 位置工作,则需要这样做,但不是必需的。

我也需要行号,发现 Bison 文档在这方面令人困惑。
简单的解决方案(使用全局 var yylloc):
在您的 Bison 文件中,只需添加 %locations 指令:

%{
...
%}
%locations
...
%%
...

在你的词法分析器中:
%{
...
#include "yourprser.tab.h"  /* This is where it gets the definition for yylloc from */
#define YY_USER_ACTION yylloc.first_line = yylloc.last_line = yylineno;
%}
%option yylineno
...
%%
...

YY_USER_ACTION 宏在您的每个 token 操作之前被“调用”并更新 yylloc。
现在您可以像这样使用@N/@$ 规则:
statement : error ';'   { fprintf(stderr, "Line %d: Bad statement.\n", @1.first_line); }

,或使用 yylloc 全局变量:
void yyerror(char *s)
{
  fprintf(stderr, "ERROR line %d: %s\n", yylloc.first_line, s);
}

关于bison - flex 究竟是如何支持 Bison 定位的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/656703/

相关文章:

c - GNU 制造商 : detect Xcode

c++ - 如何解决while/while解析中的shift/reduce冲突

grammar - Bison/YACC - 避免减少/减少与两个否定规则的冲突

regex - Lex : Breaking up long regular expressions over multiple lines

bison - Flex/Bison mini C 编译器词法和语义分析转移/减少冲突

memory-leaks - flex/bison 使用意外标记修复内存泄漏

c++ - 使用 g++、bison 和 flex 进行编译时,yyparse() 中未定义对 `yylex' 的引用

syntax-error - 为什么我的 Bison 规则不起作用

c - flex 文件中的过早 eof 错误

flex-lexer - 什么时候可以使用更新版本的 flex for windows?