您必须自己跟踪偏移量。一个简单但烦人的解决方案是:
offset += yyleng;
in every弯曲动作。幸运的是,您可以通过定义YY_USER_ACTION
宏,在令牌操作之前执行。
这可能仍然不适合你的语法,因为bison
经常先读一个令牌。所以你还需要附加值offset
对于每个词汇标记,最方便地使用位置工具(yylloc
).
编辑:添加了有关位置跟踪的更多详细信息。
以下未经过测试。您应该阅读以下两个部分中的部分flex
和bison
有关位置跟踪的手册。
The yylloc
如果您使用,全局变量及其默认类型将包含在生成的 bison 代码中--locations
命令行选项或%locations
指令,或者如果您只是在某些规则中引用位置值,请使用@
语法,类似于$
语法(即@n
是右侧对象的位置值,其语义值为$n
)。不幸的是,默认类型yylloc
uses int
s,它们的宽度不足以容纳文件偏移量,尽管您可能不打算解析这很重要的文件。无论如何,改变都很容易;你只需要#define
the YYLTYPE
宏在你的顶部bison
文件。默认YYLTYPE
is:
typedef struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
对于最小的修改,我建议保持名称不变;否则你还需要修复YYLLOC_DEFAULT
宏在你的bison
文件。默认YYLLOC_DEFAULT
确保非终端获得一个位置值,其first_line
and first_column
成员来自非终结符 RHS 中的第一个元素,其last_line
and last_column
成员来自最后一个元素。由于它是一个宏,因此它可以与各种成员的任何可分配类型一起使用,因此更改column
会员到long
, size_t
or offset_t
,只要你觉得合适:
#define YYLTYPE yyltype;
typedef struct yyltype {
int first_line;
offset_t first_column;
int last_line;
offset_t last_column;
} yyltype;
然后在你的flex
输入,您可以定义YY_USER_ACTION
macro:
offset_t offset;
extern YYLTYPE yylloc;
#define YY_USER_ACTION \
offset += yyleng; \
yylloc.last_line = yylineno; \
yylloc.last_column = offset;
完成所有这些并进行适当的初始化后,您应该能够使用适当的@n.last_column
in the ACCEPT
规则来提取接受的输入中最后一个标记末尾的偏移量。