Is this type of yacc code valid? - c

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

Related

Bison semantic predicate syntax error, stray '#'

So I am trying to use bison's semantic predicate feature, but I've been running into a few issues trying to have it work.
The problem comes when I try to compile the generated .tab.c file with gcc. I am using gcc 7.1.0 and bison 3.0.4. Here's a snippet of the compile error:
test2.tab.c: In function ‘yyuserAction’:
test2.tab.c:811:12: error: stray ‘#’ in program
if (! (#line 19 "test2.y" /* glr.c:816 */
^
test2.tab.c:811:13: error: ‘line’ undeclared (first use in this function); did you mean ‘uint’?
if (! (#line 19 "test2.y" /* glr.c:816 */
^~~~
uint
So I've taken bison's example for semantic predicate, and made it a working example:
%{
int new_syntax = 0;
int yyerror(const char* msg) { /* some error handling */ }
%}
%token id
%glr-parser
%%
prog: %empty
| prog widget
| prog flip
;
widget: %?{ new_syntax } "widget" id old_arg
| %?{ !new_syntax } "widget" id new_arg
;
flip: "flip" { new_syntax = !new_syntax; }
;
old_arg: /* something here */
;
new_arg: /* something else here */
;
%%
After playing around with the tab file, I realized that adding a newline before the #line directives resolves the syntax error, (but it feels kinda hacky directly modifying the generated file. Plus, you would have to align with some spaces in order for gcc to compute the right column position of the code).
I wonder if is this a bug with bison itself, or is it that I'm using semantic predicates wrong, or if this syntax was correct in an earlier version of gcc, or something else.
I've also tried searching the web for this issue, or for a bug already filed with bison, but I found none. (The latest bison version seems to be 3-ish years old. I would be surprised if this issue has not been addressed anywhere at all). Can someone enlighten me about this issue? Thanks.
If necessary, I could try filing a bug with bison (need to figure out how to do that), but I'm not sure if it's my own issue or what not.
As far as I can see, this bug has been present for some time (possibly since the semantic predicate feature was introduced, although it seems like someone should have tested it at some point with some version of bison.)
The simplest workaround is to turn off the generation of #line directives, which you can do by simply adding -l (or --no-lines) to the bison command line. However, that will make it harder to interpret error messages which would otherwise refer to line numbers in your bison grammar file.
As a second workaround, you could find the file c.m4, which is probably in /usr/share/bison/c.m4 (of course, that depends on your distribution). Line 462 of that file (in bison 3.0.4) reads:
if (! ($2)) YYERROR;
If you add a newline just before $2, so that it reads
if (! (
$2)) YYERROR;
then everything should work out fine. (At least, it did when I tested it.)

SWIG : What is the different between "%inline %{ %}" and "%{ %}"?

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.

I have old C program, where I can see declaration

I review code of old program and in header after include section I have the following:
extern FILE *yyin, *yyout;
TW_LOG_PROC_ERROR;
TW_TRAN_ACC;
TW_TVAL;
Extern I know, but what is below, I cannot find. I believe there are global variables, but I don't know if it is true and where to find them . Please advise.
Those could be some sort of macros or the old "implicit int rule" where objects without a specified type are considered int.
In K&R C, and pre-standard dialects of C++, a variable declared
without an explicit type name was assumed to be of type int.
The fact that they are written in caps however would suggest they are macros.
If you run ctags -R . on the entire project, you should be able to find the declaration of everything in the project. You can easily find the file and line number of every declaration in the generated tags file. There are very many plugins and programs that can handle ctags and prettify them for you.
EDIT:
or just run:
grep "TW_LOG_PROC_ERROR" -r .
grep "TW_TRAN_ACC" -r .
grep "TW_TVAL" -r .

Swig: Syntax error in input(3)

./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.

Problem with Microsoft Compiler macro expansion spaces

I have this problem in a header macro expansion under Microsoft C Compiler Preprocessor:
custom.h
.
.
# define _OTHER_INCLUDE_DIR C:\3rdparty\usr\include
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\headername>
.
.
With a header test:
headertest.h
.
.
#include _3RD_PARTY_HEADERS(stdint.h)
.
Microsoft C preprocessor expand second line like(custom.h):
#include <C:\3rdparty\usr\include\headername>
If I set :
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\ headername>
The result is:
#include <C:\3rdparty\usr\include\ stdint.h>
How I can fix that?
It looks like you want to juxtapose your directory and your header name. You use ##, like this:
# define _3RD_PARTY_HEADERS(headername) <_OTHER_INCLUDE_DIR\\##headername>
Is there no way to have the \ character sequences to be represented differently? The problem is that this is an escape character for C and C++. C99 explicitly states
If the characters ', \, ", //, or /*
occur in the sequence between the <
and > delimiters, the behavior is
undefined.
(There is a similar phrase for "..." includes.)
and I imagine that for C++ there must be something similar. So maybe you just could use / and the compiler would replace them internally to refer to the correct file on your system.
You know, most compilers have a command-line argument to add to the include path... -I or /I most likely for the Microsoft one. One doesn't usually do what you're doing here, never mind whether or not you can make it work.

Resources