C++ 是否使用未声明的标识符“yylex”和“yyin”?

C++ 是否使用未声明的标识符“yylex”和“yyin”?,c++,bison,flex-lexer,yacc,lex,C++,Bison,Flex Lexer,Yacc,Lex,以下是我的简单项目源代码: 野牛 flex.l flex_bison.cpp flex.l: %option noyywrap %{ #include <string> #include <cstring> #include "bison.tab.hpp" #define FT_SAVE_TOKEN yylval.literal = strndup(yytext, yyleng) #define FT_TOKEN(t) (yylval.token = t) %}

以下是我的简单项目源代码:

  • 野牛
  • flex.l
  • flex_bison.cpp
flex.l:

%option noyywrap

%{
#include <string>
#include <cstring>
#include "bison.tab.hpp"
#define FT_SAVE_TOKEN yylval.literal = strndup(yytext, yyleng)
#define FT_TOKEN(t) (yylval.token = t)
%}

%%

"True"                            return FT_TRUE;
"False"                           return FT_FALSE;
"let"                             return FT_LET;
"Nil"                             return FT_NIL;
"if"                              return FT_IF;
"elseif"                          return FT_ELSEIF;
"else"                            return FT_ELSE;
"switch"                          return FT_SWITCH;
"case"                            return FT_CASE;
"otherwise"                       return FT_OTHERWISE;
"for"                             return FT_FOR;
"while"                           return FT_WHILE;
"break"                           return FT_BREAK;
"continue"                        return FT_CONTINUE;
"func"                            return FT_FUNC;
"class"                           return FT_CLASS;
"type"                            return FT_TYPE;
"isinstance"                      return FT_ISINSTANCE;
"import"                          return FT_IMPORT;
"return"                          return FT_RETURN;
"void"                            return FT_VOID;
"and"                             return FT_LOGICALAND;
"or"                              return FT_LOGICALOR;
"not"                             return FT_LOGICALNOT;
"int"                             return FT_INTEGER_KEYWORD;
"uint"                            return FT_UNSIGNED_INTEGER_KEYWORD;
"double"                          return FT_DOUBLE_KEYWORD;
[ \t\v\n\f\r]                     ;
[a-zA-Z_][a-zA-Z0-9_]*            FT_SAVE_TOKEN; return FT_IDENTIFIER;
[0-9]+"."[0-9]+([Ee][+-]?[0-9]+)? FT_SAVE_TOKEN; return FT_DOUBLE;
[0-9]+([Ee][+-]?[0-9]+)?          FT_SAVE_TOKEN; return FT_INTEGER;
\"(\\.|[^\\"])*\"                 FT_SAVE_TOKEN; return FT_STRING;
"+"                               return FT_TOKEN(FT_ADD);
"-"                               return FT_TOKEN(FT_SUB);
"*"                               return FT_TOKEN(FT_MUL);
"/"                               return FT_TOKEN(FT_DIV);
"%"                               return FT_TOKEN(FT_MOD);
"!"                               return FT_TOKEN(FT_BITNOT);
"&"                               return FT_TOKEN(FT_BITAND);
"|"                               return FT_TOKEN(FT_BITOR);
"~"                               return FT_TOKEN(FT_BITCOMPLEMENT);
"^"                               return FT_TOKEN(FT_BITXOR);
"="                               return FT_TOKEN(FT_ASSIGN);
"+="                              return FT_TOKEN(FT_ADDASSIGN);
"-="                              return FT_TOKEN(FT_SUBASSIGN);
"*="                              return FT_TOKEN(FT_MULASSIGN);
"/="                              return FT_TOKEN(FT_DIVASSIGN);
"%="                              return FT_TOKEN(FT_MODASSIGN);
"=="                              return FT_TOKEN(FT_EQ);
"!="                              return FT_TOKEN(FT_NEQ);
"<"                               return FT_TOKEN(FT_LT);
"<="                              return FT_TOKEN(FT_LE);
">"                               return FT_TOKEN(FT_GT);
">="                              return FT_TOKEN(FT_GE);
"("                               return FT_TOKEN(FT_LPAREN);
")"                               return FT_TOKEN(FT_RPAREN);
"["                               return FT_TOKEN(FT_LBRACKET);
"]"                               return FT_TOKEN(FT_RBRACKET);
"{"                               return FT_TOKEN(FT_LBRACE);
"}"                               return FT_TOKEN(FT_RBRACE);
","                               return FT_TOKEN(FT_COMMA);
";"                               return FT_TOKEN(FT_SEMI);
"?"                               return FT_TOKEN(FT_QUESTION);
":"                               return FT_TOKEN(FT_COLON);
"."                               return FT_TOKEN(FT_DOT);
.                                 printf("Unknown token!n"); yyterminate();

%%
以下是错误消息:

use of undeclared identifier 'yyin'
use of undeclared identifier 'yylex`
我是否必须在使用下面代码的主功能之前定义
yyin
yylex

extern FILE *yyin;
extern int yylex(void);

即使将引用的代码添加到输出文件中,您仍然会收到关于未定义的
yylex
yyin
的投诉。您的代码只声明这些内容,而不定义它们。无论是
yacc
还是
bison
都不能为您定义这些函数,您必须自己提供这些函数(您可以使用例如
lex
flex
来生成它们)。请查看
bison
文档。RPN示例中有一个关于
yylex
函数的简短示例

编辑问题后:根据bison的文档,标题由
-d
选项生成

 Pretend that ‘%defines’ was specified, i.e., write an extra output
 file containing macro definitions for the token type names defined
 in the grammar, as well as a few other declarations.

这不包括您在序言中指定的内容,特别是
yyin
yylex
的声明。如果您需要在多个文件中声明这些声明,那么您可能希望在一个单独的头文件中声明它们,并包括来自
bison.y
的头文件以及所有需要该声明的其他文件(如
flex_bison.cpp
)。

这里有问题吗?Bison既不定义yylex也不定义yyin(尽管它称为yylex)。一切似乎都如预期的那样。(或)仅处理语法分析(即验证程序结构的正确性)。它需要一个词法分析器,f.e.或识别它的词法元素(关键字、运算符、数字、空格等)
yylex()
flex
定义
bison
每次需要令牌(即词汇项)时都会调用它。很抱歉,让人困惑的问题,我会更新它。嗨,我在这里更新了我的问题。请再次查看。是的,您需要在引用外部对象的每个翻译单元中声明外部对象。通常的方法是将声明放在头文件中。嗨,我知道我的bison规则没有被使用。这个问题是关于未声明的
yyin
yylex
的。请再次查看问题,因为我已对其进行了编辑。
use of undeclared identifier 'yyin'
use of undeclared identifier 'yylex`
extern FILE *yyin;
extern int yylex(void);
 Pretend that ‘%defines’ was specified, i.e., write an extra output
 file containing macro definitions for the token type names defined
 in the grammar, as well as a few other declarations.