Errors in making a re-entrant parser - c++

I have tried a lot, but could not figure out what the errors are.
Any detailed explanation about the this will be very helpful.
So basically i am trying to write a re-entrant parser and these are my files.
Lex1.ll
%{
#include "Globals.h"
#include "yac1.tab.hh"
extern "C"
{
int yylex(void);
}
%}
alpha [A-Za-z]
digit [0-9]
%option case-insensitive
%option bison-bridge
%option reentrant
%option noyywrap
%%
"DELETE ALL" return DELALL;
"INSERT" return INSERT;
DELETE return DELETE;
FIND return FIND;
(\+|\-)?[0-9]+ { return INT; }
\n { return ENDL; }
. ;
%%
yac1.yy
%{
#include <stdio.h>
#include "Globals.h"
%}
%pure-parser
%error-verbose
%{
#define YYPARSE_PARAM parm
#define YYLEX_PARAM ((struct parsed_vals *)parm)->scanner
#define cast ((struct parsed_vals *) parm)
void yyerror(struct parsed_vals * parm,const char *s)
{
fprintf(stderr, "error: %s\n", s);
}
extern "C"
{
int yylex(void );
// int yywrap()
// {
// return 1;
// }
}
%}
%token INSERT DELETE DELALL FIND ENDL
%union {
int ival;
float fval;
char *sval;
}
%token <ival> INT
%token <fval> FLOAT
%token <sval> STRING
%%
S:T
T: INSERT val {cast->cmd=INSERT_CMD;}
| DELETE val {cast->cmd=DELETE_CMD;}
;
val : INT ENDL {cast->type=INT_TYPE;
(cast->data).int_data=$1;}
|
FLOAT ENDL {cast->type=FLOAT_TYPE;
(cast->data).float_data=$1;}
|
STRING ENDL {cast->type=STRING_TYPE;
(cast->data).str_data=$1;}
;
%%
My main function testlex.cc
#include <stdio.h>
#include "Globals.h"
#include "lexheader.h"
#include "yac1.tab.hh"
int yyparse(void *);
yyscan_t scanner;
main()
{
struct parsed_vals foo;
const char * buffer = "inseRt 4\n";
yylex_init(&(foo.scanner));
yyset_extra(&foo, foo.scanner);
YY_BUFFER_STATE bp = yy_scan_string( buffer, foo.scanner );
yy_switch_to_buffer(bp, foo.scanner);
int a;
int ret_val = yyparse(&foo);
yy_delete_buffer(bp, foo.scanner);
if(ret_val!=0) printf("False");
printf ("hello %d\n",foo.data.int_data);
printf ("hello %d\n",foo.type);
yylex_destroy(foo.scanner);
}
Globals.h
/*
* File: Globals.h
* Author: atghosh
*
* Created on 3 August, 2013, 8:39 PM
*/
#ifndef GLOBALS_H
#define GLOBALS_H
enum CMD {INSERT_CMD=1, DELETE_CMD, FIND_CMD, DELALL_CMD};
enum TYPE {INT_TYPE=5, FLOAT_TYPE, STRING_TYPE};
struct parsed_vals{
int cmd;
int type;
union{
int int_data;
float float_data;
char *str_data;
} data;
void * scanner;
};
#endif /* GLOBALS_H */
Makefile
parser: lex1.ll yac1.yy testlex.cc
bison -d yac1.yy
flex --header-file="lexheader.h" lex1.ll
g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl
clean:
rm -rf *.o parser lexheader.h lex.yy.c lex.yy.cc parser yac1.tab.cc yac1.tab.hh
And my error list
bison -d yac1.yy
flex --header-file="lexheader.h" lex1.ll
g++ -o parser yac1.tab.cc lex.yy.c testlex.cc -lfl
yac1.tab.cc: In function ‘int yyparse(void*)’:
yac1.tab.cc:1302:16: error: too many arguments to function ‘int yylex()’
yac1.yy:20:13: note: declared here
yac1.tab.cc:1510:24: error: cannot convert ‘const char*’ to ‘parsed_vals*’ for argument ‘1’ to ‘void yyerror(parsed_vals*, const char*)’
yac1.tab.cc:1625:35: error: cannot convert ‘const char*’ to ‘parsed_vals*’ for argument ‘1’ to ‘void yyerror(parsed_vals*, const char*)’
In file included from testlex.cc:3:0:
lexheader.h:278:1: error: ‘YYSTYPE’ does not name a type
lexheader.h:280:18: error: variable or field ‘yyset_lval’ declared void
lexheader.h:280:18: error: ‘YYSTYPE’ was not declared in this scope
lexheader.h:280:28: error: ‘yylval_param’ was not declared in this scope
lexheader.h:280:51: error: expected primary-expression before ‘yyscanner’
lexheader.h:328:17: warning: ‘yylex’ initialized and declared ‘extern’ [enabled by default]
lexheader.h:328:17: error: ‘YYSTYPE’ was not declared in this scope
lexheader.h:328:27: error: ‘yylval_param’ was not declared in this scope
lexheader.h:328:50: error: expected primary-expression before ‘yyscanner’
lexheader.h:328:59: error: expression list treated as compound expression in initializer [-fpermissive]
make: *** [parser] Error 1
I am just not able to figure out what is going wrong.
Expecting detailed reply and no links.
I have already referred to these links
http://www.phpcompiler.org/articles/reentrantparser.html
http://plindenbaum.blogspot.in/2009/12/parsing-genetic-code-using-flex-and_14.html

Here's a number of issues and the corresponding fixes.
Erase the prototype of yylex from both lex1.ll and yac1.yy. You shouldn't have to define it yourself anywhere.
Add two #include's near the beginning of yac1.yy:
#include "yac1.tab.hh"
#include "lexheader.h"
Make sure you have them in this order, as the first one defines YYSTYPE which is used by the second one. This is a known issue with flex/bison lexers and parsers.
Fix the prototype and the definition of yyerror in yac1.yy. It should be:
void yyerror(const char *s);
If you need an extra parameter there, for your own purpose from your own calls, you
cannot expect the parser to provide it. In this case, define your own error handler
and use a different name.
After all this, your program compiles using your Makefile. Whether it works as expected or not, I cannot tell.

Related

Using variant in Bison and Flex

I've been rewriting a parser from c to c++, and as such I am trying to use variant with my code. However, I am not sure how to integrate it with flex, and I keep getting esoteric error messages.
My bison file looks like
%require "3"
%language "c++"
%{
// declarations
%}
%define api.value.type {std::variant<double, std::string>}
%token COMMENT
%token <double> DOUBLE
%token <std::string> STRING
// grammar
and my lexer looks like
%{
#include "y.tab.h"
%}
%option noyywrap
ID [a-zA-Z][a-zA-Z0-9_]*
%%
[ \t\n ]+ ;
\-?[0-9]+ |
\-?[0-9]+\. |
\-?[0-9]+\.[0-9]+ |
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
// other tokens
zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
%%
I am not sure of my usage of yylval, I am trying to access the variant as I would have with the %union.
I get the following error:
y.tab.h:125:18: error: ‘variant’ in namespace ‘std’ does not name a template type
typedef std::variant<double, std::string> semantic_type;
^~~~~~~
y.tab.h:197:27: error: ‘semantic_type’ does not name a type
const semantic_type& v);
^~~~~~~~~~~~~
y.tab.h:212:7: error: ‘semantic_type’ does not name a type
semantic_type value;
^~~~~~~~~~~~~
my_mdl.l: In function ‘int yylex()’:
my_mdl.l:16:3: error: ‘yylval’ was not declared in this scope
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
^~~~~~
my_mdl.l:16:3: note: suggested alternative: ‘yylex’
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
^~~~~~
yylex
my_mdl.l:16:18: error: expected primary-expression before ‘double’
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
^~~~~~
my_mdl.l:16:53: error: ‘DOUBLE’ was not declared in this scope
\-?\.[0-9]+ { yylval.emplace<double>(std::atof(yytext)); return DOUBLE;}
^~~~~~
my_mdl.l:18:10: error: ‘COMMENT’ was not declared in this scope
"//".* { return COMMENT;}
^~~~~~~
my_mdl.l:37:29: error: expected primary-expression before ‘>’ token
[a-zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
^
my_mdl.l:37:47: error: ‘STRING’ was not declared in this scope
[a-zA-Z][\.a-zA-Z0-9_]* { yylval.emplace<std::string>(yytext); return STRING;}
^~~~~~
I also get a few hundred lines of errors from my .y file such as
my_mdl.y:88:79: error: no matching function for call to ‘MOVE::MOVE(<brace-enclosed initializer list>)’
p.add_command(Command{in_place_index<5>, MOVE( {{$2, $3, $4}}, $5)});
^
In file included from parsing/symt.h:7:0,
from my_mdl.y:10:
parsing/cmd.h:44:5: note: candidate: MOVE::MOVE(const Scalable<double, 3>&, const string&)
MOVE(const Scalable<double, 3> &params, const std::string &scaleFactorName);
^~~~
MOVE is a struct defined as
struct MOVE {
MOVE(const Scalable<double, 3> &params, const std::string &scaleFactorName);
Scalable<double, 3> params; // todo equationify
std::string scale_factor_name;
};
and it is one of the types in the variant (std::variant<MOVE, etc...> Command). The strange thing is that this works normally in my code if I write
p.add_command(Command{in_place_index<5>, MOVE{{{x, y, z}}, "asdfads"}});
You have not included enough of your program to allow for a precise answer. Please see the SO help page on preparing a [mcse]. But it seems likely that you get the error
y.tab.h:125:18: error: ‘variant’ in namespace ‘std’ does not name a template type
because you haven't arranged for #include <variant> to be in your flex file.
The typedef itself is from the generated code in the header file produced by bison, but bison cannot guess what #include directives it might need, so it leaves it up to you to insert them. You must ensure that all types needed by your semantic type have been defined before you #include the bison-generated header. You could insert appropriate #include directives in the prologue block in your flex file, or you could use a %code requires block in your bison file. (Since you are using bison 3, the latter is probably the best solution.)
I have no idea what SAVE means in the errors from your bison file. I assume it is a macro you have (or have not defined), so the error would be a result of the macro expansion.
Bison actually provides its own custom type called 'variant', which is not the C++ std::variant, and supports it nicely.
https://www.gnu.org/software/bison/manual/bison.html#C_002b_002b-Variants
Bison provides a variant based implementation of semantic values for C++. This alleviates all the limitations reported in the previous section, and in particular, object types can be used without pointers.
To enable variant-based semantic values, set the %define variable api.value.type to variant (see %define Summary). Then %union is ignored; instead of using the name of the fields of the %union to “type” the symbols, use genuine types.
For instance, instead of:
%union
{
int ival;
std::string* sval;
}
%token <ival> NUMBER;
%token <sval> STRING;
write:
%token <int> NUMBER;
%token <std::string> STRING;
STRING is no longer a pointer, which should fairly simplify the user actions in the grammar and in the scanner (in particular the memory management).
To enable it, you simply specify
%define api.value.type variant
However this will also affect your lexer. I put together a small demo C++ flex/bison skeleton using the latest flex/bison binaries under Ubuntu:
https://github.com/kfsone/flub
highlights being:
/* lexer */
{string} yylval->emplace<std::string>(yytext); return Token::STRING;
/* parser */
%language "C++"
%skeleton "lalr1.cc"
%require "3.8.2"
%define api.value.type variant
/*
%define api.value.automove // use with care
*/
%define parse.assert
%define parse.trace
%define parse.error detailed
%define parse.lac full
/* ... */
/*
NB: You now use the TYPE rather than union-member name
*/
%token <std::string> STRING
/*
// ditto for nterms, but I now prefer putting them by the production itself.
%nterm <string::string> string_literal
*/
%%
/* ... */
/* Declare the type of this non-terminal, to be done here in the
productions section, you need a trailing semicolon */
%nterm <std::string> using_file;
using_file
: "using" STRING
{ $$ = $2; }
;
You can then use a much more modern AST-building approach, one thing I found helpful was to have a wrapper type of my own that captured a value AND its location.
template<typename ValueType>
struct ParsedType
{
location mLoc; // or YourParserType::location_type
ValueType mValue;
};
using ParsedString = ParsedType<std::string>;
/* ... */
%nterm <ParsedString> using_file;
using_file
: "using" STRING
{ $$ = ParsedString(#2, $2); }

SWIG: Mapping an array of a typedef

I'm using SWIG to create a Ruby Wrapper for some C++ classes. This is the signature of the C++ method which is giving me trouble:
virtual LogP wordProb(VocabIndex word, const VocabIndex *context);
This is the definition of VocabIndex:
#ifdef USE_SHORT_VOCAB
typedef unsigned short VocabIndex;
#else
typedef unsigned int VocabIndex;
#endif
This is the way I'm calling it from a Ruby script:
index = 8
context = [index]
puts ngram.wordProb(index, context)
This is the error I'm getting when I run my script:
ngram.rb:26:in `wordProb': Expected argument 2 of type VocabIndex const *, but got Array [8] (TypeError)
in SWIG method 'wordProb'
from ngram.rb:26:in `<main>'
My attempted solution:
After reading the docs (yes, I'm using SWIG 2.0), I tried this in my .i file:
%module rubylm
%{
#include "srilm-1.7.1/lm/src/Ngram.h"
%}
%include "srilm-1.7.1/lm/src/Counts.h"
%include "srilm-1.7.1/lm/src/Ngram.h"
%include "typemaps.i"
virtual LogP Ngram::wordProb(VocabIndex word, const VocabIndex *INPUT);
The swig command ran fine, but when I tried to build the wrapper library, I got this:
NgramWrapper_wrap.cxx:148:17: fatal error: tcl.h: No such file or directory
#include <tcl.h>
So I fired up a terminal (this is an Ubuntu box) and ran:
sudo apt-get install tcl-dev
This installed tcl 8.6, which placed its header files in the /usr/include/tcl8.6 directory. So I added that include directory in the Makefile line which builds NgramWrapper_wrap.o:
NgramWrapper_wrap.o: NgramWrapper_wrap.cxx
$(CC) $(CFLAGS) NgramWrapper_wrap.cxx -I $(RUBY_SRC) -I $(MISC_INCLUDE) -I $(DSTRUCT_INCLUDE) -I /usr/include/tcl8.6
However, I'm still getting build errors. And here's where I got stumped:
NgramWrapper_wrap.cxx:10812:34: error: ‘RARRAY_LEN’ was not declared in this scope
int size = RARRAY_LEN(objv[3]);
^
NgramWrapper_wrap.cxx:10816:5: error: ‘VALUE’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10816:12: error: ‘ptr’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10816:36: error: ‘RARRAY_PTR’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10819:35: error: ‘StringValuePtr’ was not declared in this scope
arg3[i]= StringValuePtr(*ptr);
^
NgramWrapper_wrap.cxx: In function ‘int _wrap_NgramCountWrapper_run(ClientData, Tcl_Interp*, int, Tcl_Obj* const*)’:
NgramWrapper_wrap.cxx:10908:34: error: ‘RARRAY_LEN’ was not declared in this scope
int size = RARRAY_LEN(objv[3]);
^
NgramWrapper_wrap.cxx:10912:5: error: ‘VALUE’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10912:12: error: ‘ptr’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10912:36: error: ‘RARRAY_PTR’ was not declared in this scope
VALUE *ptr = RARRAY_PTR(objv[3]);
^
NgramWrapper_wrap.cxx:10915:35: error: ‘StringValuePtr’ was not declared in this scope
arg3[i]= StringValuePtr(*ptr);
All I can think of is some version mismatch between Ruby, Swig and Tcl. But how can I know which Tcl version to use? I scoured the docs to no avail...
Hmm.
I just did the following
vocal.i
%module rubylm
%{
#include "Ngram.h"
%}
%include "Ngram.h"
%include "typemaps.i"
virtual LogP Ngram::wordProb(VocabIndex word, const VocabIndex *INPUT);
Ngram.h
#pragma once
#ifdef USE_SHORT_VOCAB
typedef unsigned short VocabIndex;
#else
typedef unsigned int VocabIndex;
#endif
typedef int LogP;
class NGram {
public:
LogP wordProb(VocabIndex word, const VocabIndex *context);
};
Command executed
swig2.0 -ruby -c++ vocal.i
followed by
g++ -c vocal_wrap.cxx -I/usr/include/ruby-2.1.0 -I/usr/include/x86_64-linux-gnu/ruby-2.1.0
without any errors. Have you forgot the -c++ option and why do you need tcl.h

Unknown Typename when declared in header

For some odd reason I recieve unknown type name for a typedef void variable located in a header file. Naturally i searched around the net and while it can be noted that I found similar issues it should also be noted that I am not using an IDE only Vim and Clang and don't have precompiled headers. In a separate test for the ctrie_int header, everything compiles but when I extend the implementation adding its header to the implementation file of another header I get the weird error seen below. I'm sure its a simple issue but i'm not sure what it is, any suggestions?
clang++ -Wall -Wextra -g -std=c++11 lzwtest.cpp -o lzwtest dict;
Project Compilation
.
.
.
.
.
Compiling CPP file lzwtest.cpp ...
In file included from lzwtest.cpp:2:
In file included from ./LZW.h:23:
In file included from ./ctrie_int.h:36:
./ctrie_int.ii:7:1: error: unknown type name 'Trie_Int'
Trie_Int * newTrie_Int(int defVal){return new Trie<int>(defVal);}
^
./ctrie_int.ii:7:43: error: cannot initialize return object of type 'int *' with an rvalue of type 'Trie<int> *'
Trie_Int * newTrie_Int(int defVal){return new Trie<int>(defVal);}
^~~~~~~~~~~~~~~~~~~~~
./ctrie_int.ii:9:21: error: unknown type name 'Trie_Int'
void deleteTrie_Int(Trie_Int * trie){delete ((Trie<int> *)trie);}
^
./ctrie_int.ii:11:19: error: unknown type name 'Trie_Int'
int Trie_Int_size(Trie_Int * t){return ((Trie<int> *)t)->size();}
^
./ctrie_int.ii:13:30: error: unknown type name 'Trie_Int'
int Trie_Int_getDefaultValue(Trie_Int * t){return ((Trie<int> *)t)->getDefaultValue();}
^
./ctrie_int.ii:15:23: error: unknown type name 'Trie_Int'
int Trie_Int_contains(Trie_Int * t,const char * key){return ((Trie<int> *)t)->contains(key); }
^
./ctrie_int.ii:17:18: error: unknown type name 'Trie_Int'
int Trie_Int_get(Trie_Int * t,char * key){return ((Trie<int> *)t)->get(key); }
^
./ctrie_int.ii:19:19: error: unknown type name 'Trie_Int'
void Trie_Int_put(Trie_Int * t,char * s,int val){ ((Trie<int> *)t)->put(s,val);}
^
./ctrie_int.ii:21:37: error: unknown type name 'Trie_Int'
const char * Trie_Int_longestPrefix(Trie_Int * t,char * s){return ((Trie<int> *)t)->longestPrefix(s).c_str();}
^
./ctrie_int.ii:23:23: error: unknown type name 'Trie_Int'
int Trie_Int_compress(Trie_Int * t){return ((Trie<int> *)t)->compress();}
^
10 errors generated.
Below is the header for the file being included
ctrie_int.h
#ifndef COM_WORDGAME_UTILITY_CTRIE_H
#define COM_WORDGAME_UTILITY_CTRIE_H
#ifdef __cplusplus
extern "C"{ //this is used to identify following code as C specific code which will enforce C style name mangling
#endif
//Declare a new void Type To Emulate C class
typedef void Trie_Int;
...Removed in attempt to shorten Question
#ifdef __cplusplus
}
#endif
#endif
This file uses the previous but even simple code or just the inclusion of the header file of the last causes the error described in the beginning
#ifndef COM_WORDGAME_UTILITY_CTRIE_H
#define COM_WORDGAME_UTILITY_CTRIE_H
#ifdef __cplusplus
extern "C"{ //this is used to identify following code as C specific code which will enforce C style name mangling
#endif
void compress(char src[],char dst[]);
void decompress(char src[],char dst[]);
#ifdef __cplusplus
}
#endif
#endif
//BELOW CODE WILL BE ADDED IN ANOTHER FILE
#include <stdio.h>
#include <stdlib.h>
#include "ctrie_int.h" // This causes an issue cannot find Trie_Int the functions return an odd message describing the Trie_Int was defered to an actual pointer integer
for clarity the first few lines of ctrie.ii looks like this
//#include "ctrie_int.h" //Should not be included would create cycle since ctrie_int.h declares it at the final line
#include "Trie.hpp" //C++ code
//THIS HAS TO BE COMPILED WITH C++ COMPILER TO BE COMPILED PROPERLY ANYWAY GAURDS UNEEDED
extern "C"{
//Create new Trie_Int Object
Trie_Int * newTrie_Int(int defVal){return new Trie<int>(defVal);}
....Removed In Attempt to shorten question
}
The clue is in the first stages of the error message:
Compiling CPP file lzwtest.cpp ...
In file included from lzwtest.cpp:2:
In file included from ./LZW.h:23:
In file included from ./ctrie_int.h:36: <<< Here
./ctrie_int.ii:7:1: error: unknown type name 'Trie_Int'
It appears that the file ctrie_int.ii is being included from your header before Trie_Int has been defined.

c++ compilation : what did i do wrong

I'm new to c++, and I've started a project for my internship where I have use to the Snap library from stanford (http://snap.stanford.edu/). So I have downloaded the library and I am now trying to create my own little programm using it. Sadly i can't seem to be able to compile it :(
Here are the sources :
Makefile :
CXXFLAGS += -std=c++98 -Wall
LDFLAGS += -lrt
Snap.o :
g++ -c $(CXXFLAGS) ../snap/snap/Snap.cpp -I../snap/glib -I../snap/snap -pg
simulation.o : simulation.cpp simulation.h
g++ -g -c $(CXXFLAGS) simulation.cpp
test.o : test.cpp
g++ -g -c $(CXXFLAGS) test.cpp
test : test.o Snap.o simulation.o
g++ -g $(LDFLAGS) test.o Snap.o simulation.o -I../snap/glib -I../snap/snap -lm -o test
simulation.h
#ifndef SIMULATION
#define SIMULATION
#include <vector>
#include "../snap/snap/Snap.h"
class Simulation{
public:
Simulation():score(-1),nNodes(-1),nEdges(-1), dMax(-1){};
Simulation(int nN, int nE, int d);
Simulation(int d, PUNGraph g);
void setDMax(int d){ dMax = d; }
double getScore(){ return score; }
int getNNodes(){ return nNodes; }
int getNEdges(){ return nEdges; }
int getDMax(){ return dMax; }
PUNGraph getGraph(){ return graph; }
std::vector<int> getAlignment(){ return alignment; }
double computeEnergy();
private:
double score;
int nNodes;
int nEdges;
int dMax;
PUNGraph graph;
std::vector<int> alignment;
};
#endif
simulation.cpp
#include "simulation.h"
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include "../snap/snap/Snap.h"
Simulation::Simulation(int nN, int nE, int d){
nNodes = nNodes;
nEdges = nEdges;
dMax = dMax;
graph = TSnap::GenRdnGnm<PUNGraph>(nNodes,nEdges);
for(int i=1; i<=nNodes; i++){
alignment.push_back(i);
}
random_shuffle(alignment.begin(),alignment.begin()+nNodes);
computeEnergy();
}
Simulation::Simulation(int d, PUNGraph g){
nNodes = graph->GetNodes();
nEdges = graph->GetEdges();
dMax = d;
graph = g;
for(int i=1; i<=nNodes; i++){
alignment.push_back(i);
}
random_shuffle(alignment.begin(),alignment.begin()+nNodes);
computeEnergy();
}
double computeEnergy(){
return 0.0;
}
test.cpp
#include<stdlib.h>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include "simulation.h"
#include "../snap/snap/Snap.h"
int main(int argc, char** argv){
Simulation sim(5000,30000,30);
}
I don't think my compilation problems come from Snap itself and it might very well be only from my poor knowledge of c++ and how the includes an so on are working.
Here is what I get after running make :
g++ -g -c -std=c++98 -Wall simulation.cpp
In file included from /usr/include/c++/4.5/bits/stl_algo.h:61:0,
from /usr/include/c++/4.5/algorithm:63,
from simulation.cpp:5:
/usr/include/c++/4.5/bits/algorithmfwd.h:347:41: error: macro "max" passed 3 arguments, but takes just 2
/usr/include/c++/4.5/bits/algorithmfwd.h:358:41: error: macro "min" passed 3 arguments, but takes just 2
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected unqualified-id before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected initializer before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:347:5: error: template declaration of ‘const _Tp& std::max’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected unqualified-id before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected initializer before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:358:5: error: template declaration of ‘const _Tp& std::min’
In file included from /usr/include/c++/4.5/algorithm:63:0,
from simulation.cpp:5:
/usr/include/c++/4.5/bits/stl_algo.h: In function ‘void std::__merge_sort_loop(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Distance)’:
/usr/include/c++/4.5/bits/stl_algo.h:3172:26: error: expected unqualified-id before ‘(’ token
/usr/include/c++/4.5/bits/stl_algo.h: In function ‘void std::__merge_sort_loop(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Distance, _Compare)’:
/usr/include/c++/4.5/bits/stl_algo.h:3202:26: error: expected unqualified-id before ‘(’ token
simulation.cpp: In constructor ‘Simulation::Simulation(int, int, int)’:
simulation.cpp:11:13: error: ‘GenRdnGnm’ is not a member of ‘TSnap’
simulation.cpp:11:38: error: expected primary-expression before ‘>’ token
simulation.cpp:11:47: warning: left-hand operand of comma has no effect
I'd be very glad if some one could help resolve my problems (and if you feel like giving some c++/programming wisdom in the process i'd be even happier :) )
Ortholle
The Snap library headers contain the unfortunate macro definitions:
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
This will cause problems with code that uses (or defines) std::min and std::max.
You can get around this by making sure to include STL headers before Snap, or possibly by adding
#undef min
#undef max
after including the Snap.h header.
Another problem with your code: What's with all those extraneous #includes? Example: Your test.cpp #includes a whole bunch of stuff it doesn't need. All that test.cpp needs is (or should need) simulation.h. simulation.cpp has a similar problem with far too many #includes.
Don't #include something in a file that isn't used in that file.
(Aside: that random_shuffle in simulation.cpp should be std::random_shuffle).
None of these fixes are going to help with the base problem, which is that the Snap library 'conveniently' defines max and min as macros. You don't need these, so undef them.

compilation error about exceptions

I met some compilation error but do not know what the problem is. The code seems not use exception, but the error is about it.
//in misc.h:
char *basename(char *name); // line 94
// in misc.cc:
char *basename(char *name) { // line 12
char *result = name;
while(*name) {
if(*name == '/') result = name + 1;
name++;
}
return result;
}
Compilation error
g++ -pipe -W -Wall -fopenmp -ggdb3 -O2 -c -o misc.o ../../src/misc.cc
../../src/misc.cc: In function ‘char* basename(char*)’:
../../src/misc.cc:12: error: declaration of ‘char* basename(char*)’ throws different exceptions
../../src/misc.h:94: error: from previous declaration ‘char* basename(char*) throw ()’
make: *** [misc.o] Error 1
Does someone have some clue? Thanks and regards!
EDIT:
Files included in misc.h are
#include <iostream>
#include <cmath>
#include <fstream>
#include <cfloat>
#include <stdlib.h>
#include <string.h>
EDIT:
in misc.i generated by -E option,
extern "C++" char *basename (char *__filename)
throw () __asm ("basename") __attribute__ ((__nonnull__ (1)));
extern "C++" __const char *basename (__const char *__filename)
throw () __asm ("basename") __attribute__ ((__nonnull__ (1)));
# 640 "/usr/include/string.h" 3 4
# 1 "/usr/include/bits/string3.h" 1 3 4
# 23 "/usr/include/bits/string3.h" 3 4
extern void __warn_memset_zero_len (void) __attribute__((__warning__ ("memset used with constant zero length parameter; this could be due to transposed parameters")));
# 48 "/usr/include/bits/string3.h" 3 4
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__, __artificial__)) void *
memcpy (void *__restrict __dest, __const void *__restrict __src, size_t __len) throw ()
{
return __builtin___memcpy_chk (__dest, __src, __len, __builtin_object_size (__dest, 0));
}
...
# 641 "/usr/include/string.h" 2 3 4
...
You may be picking up the definition of basename() from libgen.h. On my OpenSUSE system, the version in libgen.h is defined with "throw ()" at the end (via the __THROW macro).
One thing you can try is to tell gcc to only run the preprocessor stage by adding the -E flag and then search for basename to see what is being defined:
g++ -pipe -W -Wall -fopenmp -ggdb3 -O2 -E -o misc.i ../../src/misc.cc
If that is happening, you'll either need to drop the include of libgen.h, match the throw specifier or change the name of your function.
" ../../src/misc.h:94: error: from previous declaration ‘char* basename(char*) throw ()’ "
I'm reading that as having been declared twice, once with throw() and once without.
Compiles for me, same flags.
g++ (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4
Your error says that there is a declaration of ‘char* basename(char*) throw ()’
try opening misc.h and searching for throw in the entire file, to see if you put the throw in yourself and just forgot about it.