据我所知,如果我需要返回lex中不是整数类型(默认情况下)的令牌(默认情况下),我必须重新定义YYSTYPE以使其具有这样做的能力。
但是我收到一些奇怪的错误,如下。
我有一个名为symbol.h的文件,在其中放置了所需的结构,并且同时包含在.l文件(lex)和.y文件(yacc)中
struct type
{
int val;
double dval;
bool bval;
string* sval;
idData* iddata;
int type;
};
// typedef type YYSTYPE;
// #define YYSTYPE type
如果我使用#define,我会得到这样的东西:
duplicate symbol __Z13yylex_destroyv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-7b46a5.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-64e257.o
连同链接错误
对于typedef,它显示了以下内容:
In file included from scanner.l:6:
./y.tab.hpp:146:13: error: typedef redefinition with different types ('int' vs 'type')
typedef int YYSTYPE;
^
./symbols.h:48:14: note: previous definition is here
typedef type YYSTYPE;
^
那么如何使自定义YYSTYPE正常工作?
编辑:
我的解析器的声明部分:
%{
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <vector>
#include "symbols.h"
#include <string>
#include "lex.yy.cpp"
#define TRACE_FLAG 1
#define trace(t) if (TRACE_FLAG) cout << "TRACE => " << t <<endl;
using namespace std;
void yyerror(string s);
vector<SymbolTable> stbs;
idData* lookupAll(string s, bool ptr=false);
%}
/* tokens */
%token LESS_EQUAL GREATER_EQUAL EQUAL NOT_EQUAL AND OR ASSIGNMENT
%token BEGIN_LEX BREAK CASE CONST CONTINUE DO ELSE END EXIT FN FOR IF IN LOOP MODULE OF PRINT PRINTLN PROCEDURE READ RECORD REPEAT RETURN THEN TYPE USE UTIL VAR WHILE
%token ARRAY BOOLEAN CHAR INTEGER REAL STRING
%token <sval> IDENTIFIER
%token <val> INT_CONST
%token <bval> BOOL_CONST
%token <dval> REAL_CONST
%token <sval> STR_CONST
/* type declaration for non-terminal symbols */
%type <iddata> constant_value expression
%type <type> var_type
/* precedence */
%left OR
%left AND
%left '~'
%left '<' '>' LESS_EQUAL GREATER_EQUAL EQUAL NOT_EQUAL
%left '+' '-'
%left '*' '/' '%'
%nonassoc UMINUS
/* start of the program */
%start program
对于扫描仪。l:
%{
#include <iostream>
#include <string>
#include <map>
#include "symbols.h"
#include "y.tab.hpp"
using namespace std;
#define LIST strcat(buf,yytext)
#define SHOW_TOKEN 0
#define token(t) {LIST; if(SHOW_TOKEN) printf("<%s>\n",#t);}
#define tokenInteger(t,i) {LIST; if(SHOW_TOKEN) printf("<%s:%d>\n",t,i); }
#define tokenString(t,s) {LIST; if(SHOW_TOKEN) printf("<%s:%s>\n",t,s);}
#define MAX_LINE_LENG 256
int linenum = 1;
char buf[MAX_LINE_LENG];
string str;
%}
whitespace [ \t]+
digit [0-9]
letter [a-zA-Z]
identifier {letter}({digit}|{letter})*
integer [+-]?{digit}+
real [+-]?{digit}+"."{digit}+([Ee][+-]{digit}+)?
%x COMMENT_MODULA
%x COMMENT_C
%x STR
symbols.h的内容:
#ifndef SYMBOLS_H
#define SYMBOLS_H
#include <iostream>
#include <map>
#include <vector>
#include <stdio.h>
#include <string>
using namespace std;
enum variable_type{
t_INT,
t_BOOL,
t_REAL,
t_STR,
t_ARRAY,
t_VOID
};
struct idData
{
int type = t_VOID; // enum type
/* id value */
int val = 0; // integer
bool bval = false; // boolean
double dval = 0; // float
string* sval = new string(""); // string
vector<idData> aval; // array
int arr_type = t_VOID; // enum type
idData();
idData(int type);
};
void print_id(idData id);
struct type
{
int val;
double dval;
bool bval;
string* sval;
idData* iddata;
int type;
};
// typedef type YYSTYPE;
#define YYSTYPE type
class SymbolTable {
private:
map<string, idData> symbols;
public:
idData* lookup(string s, bool ptr);
bool insert(string s, idData value);
idData* get_id_ptr(string s);
int dump(string function_name);
};
#endif
最后是生成文件:(我正在Mac上,顺便说一句。)
TARGET = parser
LEX = flex
YACC = yacc
YACCFLAG = -d
CXX = g++
CXXFLAG = -std=c++11 -Wno-deprecated-register
.PHONY: all clean
all: $(TARGET)
y.tab.cpp: parser.y
$(YACC) $(YACCFLAG) -o $@ $^
lex.yy.cpp: scanner.l
$(LEX) -o $@ $^
$(TARGET): lex.yy.cpp y.tab.cpp symbols.cpp symbols.h
$(CXX) $(CXXFLAG) lex.yy.cpp y.tab.cpp symbols.cpp -o $@ -ll -ly
clean:
$(RM) $(TARGET) lex.yy.cpp y.tab.*
默认情况下,yacc链接到macOS上的bison,我尝试使用byacc来获得基本相同的结果。
错误消息:
g++ -std=c++11 -Wno-deprecated-register lex.yy.cpp y.tab.cpp symbols.cpp -o parser -ll -ly
duplicate symbol __Z13yylex_destroyv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z5yylexv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z10yyget_textv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z9yyget_outv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z12yyget_linenov in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z8yyget_inv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z11yyget_debugv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z10yyget_lengv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z18yypop_buffer_statev in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z6yyfreePv in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yytext in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yyout in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _str in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yylineno in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yyin in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z9yyreallocPvm in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _linenum in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z7yyallocm in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z14yy_scan_bufferPcm in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z12yyset_linenoi in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z11yyset_debugi in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z13yy_scan_bytesPKci in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z16yy_create_bufferP7__sFILEi in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yy_flex_debug in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _yyleng in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol _buf in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z19yy_switch_to_bufferP15yy_buffer_state in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z15yy_flush_bufferP15yy_buffer_state in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z16yy_delete_bufferP15yy_buffer_state in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z19yypush_buffer_stateP15yy_buffer_state in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z14yy_scan_stringPKc in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z9yyset_outP7__sFILE in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z9yyrestartP7__sFILE in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
duplicate symbol __Z8yyset_inP7__sFILE in:
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/lex-51b52c.o
/var/folders/50/dhxd49xd3f5c2rkvsdspk7r40000gn/T/y-7ea26f.o
ld: 34 duplicate symbols for architecture x86_64
答案 0 :(得分:1)
我认为可能有更好的解决方案,因为您似乎要针对的是带标签的工会,而野牛确实具有一些允许这样做的功能。但是无论如何,您的尝试失败有两个不同的原因:
除非您typedef int YYSTYPE
,否则野牛生成的头文件将包含#define YYSTYPE
。 (typedef
由#ifndef YYSTYPE
保护。)不支持YYSTYPE
的用户typedef。
您可以分别编译扫描器和解析器。因此,如果您还也 #include "lex.yy.cpp"
进入解析器,最终将其两次编译到您的项目中。因此出现重复的符号错误。