Как заставить переопределение YYSTYPE работать правильно? - PullRequest
0 голосов
/ 14 мая 2019

Насколько я знаю, если мне нужно вернуть токены, которые не имеют целочисленных типов (по умолчанию) в lex, я должен переопределить YYSTYPE, чтобы дать ему возможность сделать это.

Но яЯ получаю некоторые странные ошибки следующим образом.

У меня есть файл с именем symbols.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 работало правильно?

РЕДАКТИРОВАТЬ:

часть объявлениямой parser.y:

%{
#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

содержимое символов .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

и, наконец, make-файл :(Я делаю это на 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, и я пробовал с 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

структура моего кода

1 Ответ

1 голос
/ 14 мая 2019

Я думаю, что, возможно, есть лучшее решение, так как то, к чему вы, похоже, стремитесь, - это помеченный союз, и у бизона есть некоторые особенности, которые позволяют это сделать.Но в любом случае ваши попытки не удаются по двум различным причинам:

  1. Файл заголовка, созданный зубрами, включает typedef int YYSTYPE, если вы не #define YYSTYPE.(typedef защищено #ifndef YYSTYPE.) Пользовательские значения типа YYSTYPE не поддерживаются.

  2. Вы компилируете сканер и анализатор независимо.Поэтому, если вы также #include "lex.yy.cpp" добавите в свой анализатор, вы в итоге дважды скомпилируете его в свой проект.Отсюда повторяющиеся ошибки символов.

...