我想知道是否有可能在yacc和lex中获取令牌的值。例如,假设我的lex文件中有这样的定义:
";" {printf("%s ", yytext); return SEMICOLON;}
现在,可以在lex的主要功能中访问SEMICOLON
的值了吗?
答案 0 :(得分:2)
我想知道是否有可能在yacc中获取令牌的值 和lex。
从一般意义上讲,是的,当然是。
例如,假设我在lex中有这样的定义 文件:
";" {printf("%s ", yytext); return SEMICOLON;}
现在,是否可以在主目录中访问SEMICOLON的值 lex的功能?
您的问题似乎基本上与标识符SEMICOLON
的范围有关,但这取决于其声明的形式和位置。在评论中,您写的是您的特定情况,
它在lex文件中定义。
%%
部分之后
我认为这是您的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;}