What I understood from the documentation is that what is between %{ %} is inserted into the wrapper, what about %inline %{ %} ?
Is it the same? If it is not, what are the differences?
Maybe we can find many occurences of %inline %{ %} but only one occurence of %{ %}?
Thank you a lot!
You can have any number of occurrences of either types of block. The %{ ... }% just inserts what is in the block verbatim in the file generated by SWIG. It is used so that the generated file will compile, i.e. you normally put there whatever includes and defines and such that are required in order to get the generated file to compile.
OTOH, From the docs:
The %inline directive inserts all of the code that follows verbatim into the header portion of an interface file. The code is then parsed by both the SWIG preprocessor and parser.
So the %inline %{ ... %} does two things rather: it puts the declaration in the generated wrapper file, AND it causes SWIG to generate the wrapper code so that functions etc in the block can be called from the target language (Python, Lua, whatever). This is not the case for %{ ... }%: code in such block does not get wrapped, just gets dumped verbatim in the generated wrapper file.
Don't be afraid to open up the *_wrap.cpp that SWIG generates: put some easily searchable code in the two types of blocks and look at where they end up in the wrapper file, and what additional code got generated.
Related
For example:
#include "pathtoheader1/header1.hh"
##include "pathtoheader2/header2.hh"
What is the difference between these two preprocessor directives?
Edit
From what I can tell, the ##include directive, in the context of the program I am working with, will prepend -I flags to the specified include path.
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels
The compiler will now look for:
/models/pathtoheader1/header1.hh
instead of
/pathtoheader1/header1.hh
These flags are stored in a .mk file.
Additional Information
I am using NASA's Trick Simulation environment to build a simple 2-body simulation of the earth orbiting the sun. The specific tool I am using is called 'trick-CP', Trick's compilation tool.
https://github.com/nasa/trick
## is the token pasting operator in both the C and C++ preprocessors. It's used to concatenate two arguments.
Since it requires an argument either side, a line starting with it is not syntactically valid, unless it's a continuation of a previous line where that previous line has used the line continuation symbol \ or equivalent trigraph sequence.
Question is about NASA Trick. Trick extends C and C++ language with its own syntax.
From Trick documentation:
Headers files, that supply data-types for user-defined models should be included using ##include . Note the double hash (#).
The second one is a syntax error in C++, and I am pretty sure it is a syntax error in C too. The ## preprocessor operator is only valid inside a preprocessor macro (where it forces token pasting).
Here is what the Trick Documentation says about include:
Include files
There are two types of includes in the S_define file.
Single pound "#" includes.
Include files with a single pound "#" are parsed as they are part of the S_define file. They are treated just as #include files in C or C++ files. These files usually include other sim objects or instantiations as part of the S_define file.
Double pound "#" includes.
Include files with a double pound "##" are not parsed as part of the S_define file. These files are the model header files. They include the model class and structure definitions as well as C prototypes for functions used in the S_define file. Double pound files are copied, minus one pound, to S_source.hh.
Also here is a link to where it talks about it in the Trick documentation: https://nasa.github.io/trick/documentation/building_a_simulation/Simulation-Definition-File
Say that the names of the parsers are parser_1 and parser_2.
parser_1:
Bison file = parser_1.y
Flex file = parser_1.l
After Compiling with gcc I get my paser in the following two files:
parser_1.tab.c and parser_1.lex.yy.c
Similary my parser_2 consitst of:
parser_2.tab.c and parser_2.lex.yy.c
I am trying to compile both the parsers together because me program needs both the parsers. I cannot replace the two parsers by one parser because the following two reasons. The grammars are completely different and the parsers are to be invoked at entirely different statges of my program.
gcc parser_1.tab.c parser_1.lex.yy.c \
parser_2.tab.c parser_2.lex.yy.c \
my_program.c -lfl
It gives me error that some functions like yylex (), yyparse () etc. have been defined multiple times, which is understandable.
My Question:
Is there some method by which I can have the two parsers in my program?
Or please give your suggestions.
To invoke use multiple parsers from a C program there are two methods:
Use multiple start symbols, if grammars are closely related.
For details see
http://www.gnu.org/software/bison/manual/html_node/Multiple-start_002dsymbols.html
Change the prefix yy for parser(s). This would remove all the name conflicts. A new prefix can be specified using the option -Dapi.prefix={prefix}.
You will need to modify the prefixes of the lexical analyser also, if you are using a separte lexical analyser. This can be achieved by using the --prefix=PREFIX flag.
For details about renaming in Bison see: http://www.gnu.org/software/bison/manual/html_node/Multiple-Parsers.html
For details about renaming in Flex see: http://westes.github.io/flex/manual/#Code_002dLevel-And-API-Options
In flex you will need to specify %option noyywrap as the very first line of the .l file. For details see: http://westes.github.io/flex/manual/Generated-Scanner.html#index-yywrap_0028_0029
I have two lexers - shell.l and javascript.l with prefixes (%option prefix) shell and javascript respectively(%option prefix="shell" in shell.l and %option prefix="javascript" in javascript.l).
I am calling the lexers from another file ( main_file.c) sequentially as:
somefunc(){
.....
shelllex();
......
javascriptlex();
}
In order to call these, I have included the header files of these two lexers in main_file.c as:
#include <.....>
#include "lex.shell.h"
#include "lex.javascript.h"
And, I create these headers when I compile the flex files as:
flex --header-file=lex.shell.h shell.l
flex --header-file=lex.javascript.h javascript.l
gcc -o lang lex.shell.c lex.javascript.c main_file.c -lfl
When I compile main_file.c, I get redefiniton error as below:
In file included from code_detector.c:16:0:
lex.javascript.h:227:29: error: redefinition of ‘yy_nxt’
static yyconst flex_int16_t yy_nxt[][128] =
^
In file included from code_detector.c:15:0:
lex.shell.h:227:29: note: previous definition of ‘yy_nxt’ was here
static yyconst flex_int16_t yy_nxt[][128] =
I have gone through several other SO posts, but didn't find much help.
I would greatly appreciate any help in resolving these!
Thanks!
Apparently, there was a bug which causes the scanner transition table yy_nxt to be incorrectly written to the header file if %option full is present. This should be fixed in the latest version of flex (2.5.39).
If you don't want to upgrade your version of flex, a simple workaround would be to avoid using %option full. You may well find that the speed penalty is not measurable.
./theheader.h:349: Error: Syntax error in input(3).
Offending line:
string read_gdbm(GDBM_FILE dbf, string key_str, bool show_err = gbls.verbose);
Any ideas?
Typically, a syntax error in SWIG means that it can't understand the line in question (which can be annoying, because the line numbers don't follow macros such as %defines). So I suggest you check that string (should it be std::string? has it been defined?), GDBM_FILE (has it been defined? should it be in a namespace?) and maybe gbls.verbose (has it been defined?) make sense to SWIG. It may help to run swig with the -E option (be sure to redirect the stdout), find the corresponding line and search backward for each type involved. You may need to add some #includes.
Also check the previous line, to ensure you're not missing a semicolon, or something like that.
As a side note, I've run into the same issue for different reasons: I was trying to use a vector < vector < double >>. Now the ">>" character sequence mustn't be used with templates according to the C++99 standard, hence the swig error message popped up. The solution was to simply add an extra space to separate them.
I hit a similar error. I'll clarify my process, hope it can be helpful.
lib.i:
...
%begin %{
#include "header1.h"
%}
...
%include "header1.h"
header1.h:
19 typedef struct T {
...
23 } PACKED TlvHdr;
The error message just as below
./header1.h:23: Error: Syntax error in input(3).
I check the SWIG doc(http://www.swig.org/Doc1.3/SWIG.html 5.7.1) and found that the syntax error is so common, it's probably caused by a SWIG bug.
The doc recommended when encountering a syntax error to use #ifndef SWIG to omit statements that will make SWIG parser issue an error. So I changed the header1.h file, then the error disappeared.
header1.h:
#ifndef SWIG
19 typedef struct T {
...
23 } PACKED TlvHdr;
#endif
If you can't modify theheader.h file, you can make a new header file that just contains the declarations you need and replace the file from theheader.h to your new header file at %include directive
I had a similar issue and -E helped me understand that a macro definition was hidden inside an #ifndef SWIG block. I suspect that here it does not see the definition of GDBM_FILE, likely because it does not recurse.
%{
#ifdef abc
.
.
. // C declarations
.
%}
.
. // Yacc Declaration
.
%%
.
. //expected inputs and corresponding actins
.
%%
#endif
Although this code compiles for me even then I strongly feel #ifdef abc is not placed correctly. Is this type of code valid for Yacc.
I have very little experience in YACC.
Thanks
The code between %{ and %} is put verbatim at the top of the generated C source file, while the code after the rules is also put verbatim but at the end of the generated file.
So the answer to your question is: Yes, it's correct in both Yacc and the generated source. However, from a readability point of view, the Yacc-code might be considered dubious.