如何重新定义YYSTYPE才能正常工作?

时间:2019-05-13 22:32:10

标签: yacc lex

据我所知,如果我需要返回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

the structure of my code

1 个答案:

答案 0 :(得分:1)

我认为可能有更好的解决方案,因为您似乎要针对的是带标签的工会,而野牛确实具有一些允许这样做的功能。但是无论如何,您的尝试失败有两个不同的原因:

  1. 除非您typedef int YYSTYPE,否则野牛生成的头文件将包含#define YYSTYPE。 (typedef#ifndef YYSTYPE保护。)不支持YYSTYPE的用户typedef。

  2. 您可以分别编译扫描器和解析器。因此,如果您还 #include "lex.yy.cpp"进入解析器,最终将其两次编译到您的项目中。因此出现重复的符号错误。