是否可以获取代币的价值?

Is it possible to get the value of tokens?

我想知道是否可以在 yacc 和 lex 中获取标记的值。例如,假设我的 lex 文件中有这样一个定义:

";" {printf("%s ", yytext); return SEMICOLON;}

现在,是否可以在 lex 的主函数中访问 SEMICOLON 的值?

I was wondering if it is possible to get the values of tokens in yacc & lex.

一般意义上,是的,当然是。

For instance, let's say that I have such a definition in my lex file:

";" {printf("%s ", yytext); return SEMICOLON;}

Now, is it possible to access the value of SEMICOLON in the main function of lex?

您的问题似乎基本上是关于标识符 SEMICOLON 的范围,但这取决于其声明的形式和位置。在评论中,您在特定情况下写道,

It is defined inside the lex file. after the %% part

我将其视为您的 lex 输入文件中的这些内容:

%%

/* ... no rules before this */

    #define SEMICOLON 59

/* ... */

";" {printf("%s ", yytext); return SEMICOLON;}

在这种情况下,宏定义被发送到生成的 yylex() 函数的主体中,在任何代码实现扫描规则之前。从那一点到生成的 C 源文件的末尾,它将是可见的,除非明确取消或重新定义,但未指定可能存在的其他函数。另请注意,如果您将其声明为变量而不是宏,那么它将是扫描仪函数的局部变量。

这不是解决问题的方法。

由 lex 生成的对 C 源代码全局的声明应该放在定义部分,包含在 %{%} 之间。最佳做法是将此类内容放在顶部或非常靠近顶部:

%{
#define SEMICOLON 59
%}

%%

/* ... */

";" {printf("%s ", yytext); return SEMICOLON;}

这将导致定义被放置在顶部范围内,接近文件的顶部。

但是,就其本身而言,它不提供对项目中任何其他源文件的可见性。如果您使用 yacc 来生成解析器以配合基于 lex 的扫描器,那么惯用的做法是让 yacc 还生成一个包含令牌标识符的 C 头文件(默认名称:y.tab.h),然后将相应的 #include 指令放入您的 lex 输入中,而不是直接 #define 那里的符号。如果您不使用 yacc 但确实想共享令牌标识符和代码,您可以手动执行类似的操作。

%{
#include "y.tab.h"
%}

%%

/* ... */

";" {printf("%s ", yytext); return SEMICOLON;}