gcc giving error on printf while compiling lex output - lex

For the example.l lex file I get the error below. If I comment out the printf it goes away. I though that the top section of the lex specification could contain any arbitrary C code between the %{ and %}. I need to be able to print some output before lex matches anything. What is wrong with what I have done and how do I fix it?
$ cat example.l
%{
#include <stdio.h>
printf("foobar\n");
%}
%%
. ECHO;
$ lex example.l
$ gcc -g -L/usr/lib/flex-2.5.4a -lfl -o example lex.yy.c
example.l:3: error: expected declaration specifiers or '...' before string constant
example.l:3: warning: data definition has no type or storage class
example.l:3: error: conflicting types for 'printf'
example.l:3: note: a parameter list with an ellipsis can't match an empty parameter name list declaration

If you look at the code here, you can see that one of two things is happening here ... either you are doing a #include inside a function body which doesn't make sense, or you are calling printf() outside any function, which is equally wrong.
Now, when you take into account this is flex, it's the latter. You were probably shooting for something a little more like this:
%{
#include <stdio.h>
%}
%%
. ECHO;
%%
int main() {
printf("foobar\n");
while (yylex() != 0);
return 0;
}

Related

Program exited with error code 04

I'm trying to run a program with perl to print "A" 512 times through gdb. It returned with code 04. I started slowly going down to 511 then 510 and so on. But it still returned with code 04. Is this how it's supposed to be? If not, what am I doing wrong? Thanks for your answers.
Code:
#include <stdio.h>
int main(int argc, char * argv[])
{
char buf[256];
if(argc == 1)
{
printf("Usage: %s input\n", argv[0]);
exit(0);
}
strcpy(buf,argv[1]);
printf("%s", buf);
}
And I'm running from gdb:
run perl -e 'print "A" x 512'
There's no reason to involve either perl or gdb for this.
As of the 1989/1990 C standard, reaching the } at the end of main returns an undefined status to the environment. (The actual status of 4 in your case is probably the value returned by printf, which is the number of characters it printed. The way you invoked the program, argv[0] points to the string "perl", which is 4 characters long. But you absolutely should not count on that behavior.)
The 1999 standard introduced a new rule (inspired by C++): reaching the end of main does the equivalent of return 0;. But gcc by default uses the C90 standard plus GNU extensions (equivalent to -std=gnu90).
Add a return 0; to the end of your main function and/or compile your C program with an option that specifies a later standard, such as -std=c99 (or -std=gnu99 if you want to use GNU-specific extensions).
Finally, it looks like you were trying to print 512 'A' characters, but you were invoking your program with the arguments:
perl -e 'print "A" x 512'
That's three arguments, and your program ignores all but the first, the 4-character string "perl". The remaining arguments were meant to be passed to the Perl interpreter, but you didn't invoke the Perl interpreter.
One correct way to do this would be:
./foo $(perl -e 'print "A" x 512')
where foo is the name of your program. But that would cause undefined behavior (possibly a program crash, or it might appear to "work" if you're unlucky), because you copy the string pointed to by argv[1] into an array of only 256 characters. For this simple program, that's easily avoided by not copying the string.
And your program's output doesn't end with a newline, which can cause problems. On a UNIX-like system, the program's output will likely be printed on the same line as your next shell prompt -- or the output might not be visible at all.
To see the program's exit status, type:
echo $?
(This assumes you're using bash or a similar shell.)

Double macro expansion in (AVR-)GCC

please excuse me if this question has already been answered elsewhere, but I'm not sure what to search for.
I am passing a value from a batch file, though a makefile, and to a header file, like so:
(Using AVR-GCC 4.5.2)
Batch:
make ADDR=FOO
Makefile:
CFLAGS += -DADDR=$(ADDR)
...
gcc $(CFLAGS) main.c
This is the header file main.h, included by main.c; it is supposed to select a specific pinout at compile-time, based on the value of ADDR:
#include "defs.h"
#if ADDR == FOO
... // Select pinout 1
#elif ADDR == BAR
... // Select pinout 2
#endif
The comparison values FOO and BAR are constants defined in a global header file defs.h included by main.h:
#define FOO 23
#define BAR 42
Now the problem: The comparisons don't work, ADDR constantly reads as 0. This seems to be because the preprocessor does not resolve ADDR before the comparison, i.e. expand FOO to 23. Telling the compiler to do this expansion would be helpful.
Of course it works if I pass ADDR=23 directly in the batch file, but for flexibility I want to use the aliases from defs.h instead of fixed numeric constants.
By the way, the following works if placed in main.c:
int addr_val = ADDR; // is now 23
Maybe there is a simple solution I am not aware of right now. Please feel free to contribute.
Have a nice day!

.... undeclared (first use in this function)?

I have a simple code in lex language and i generate lex.yy.c with Flex.
when i want to compile lex.yy.c to .exe file i get some error like "undeclared (first use in this function) " ! when i search in web i understand i need a Const.h file, so i want to generate that file.
how i can do this ?
Some Errors:
35 C:\Users\Majid\Desktop\win\lex.l STRING' undeclared (first use in this function)
38 C:\Users\Majid\Desktop\win\lex.lLC' undeclared (first use in this function)
39 C:\Users\Majid\Desktop\win\lex.l `LP' undeclared (first use in this function)
....
Beginnig of The Code is :
%{int stk[20],stk1[20];
int lbl=0,wlbl=0;
int lineno=0;
int pcount=1;
int lcount=0,wlcount=0;
int token=100;
int dtype=0;
int count=0;
int fexe=0;
char c,str[20],str1[10],idename[10];
char a[100];
void eatcom();
void eatWS();
int set(int);
void check(char);
void checkop();
int chfunction(char *);%}
Digit [0-9]
Letter [a-zA-Z]
ID {letter}({letter}|{digit})*
NUM {digit}+
Delim [ \t]
A [A-Za-z]]
%%
"/*" eatcom();
"//"(.)*
\"(\\.|[^\"])*\" return (STRING);
\"(\\.|[^\"])*\n printf("Adding missing \" to sting constant");
"{" {a[count++]='{';fexe=0;eatWS();return LC;}
"(" {a[count++]='(';eatWS();return LP;}
"[" {a[count++]='[';eatWS();return LB;}
"}" {check('{');eatWS();
if(cflag)
{
//stk[lbl++]=lcount++;
fprintf(fc,"lbl%d:\n",stk[--lbl]);
//stk[lbl++]=lcount++;
printf("%d\n",stk[lbl]);
cflag=0;
}
return RC;
}
"]" {check('[');eatWS();return RB;}
")" {check('(');eatWS();return RP;}
"++" | "--" return INCOP;
[~!] return UNOP;
"*" {eatWS();return STAR;}
[/%] {eatWS();return DIVOP;}
"+" {eatWS();return PLUS;}
"-" {eatWS();return MINUS;}
You need a .h file with the definitions. You can write it by hand, but typically this file is generated by Bison. The two tools Flex and Bison are very often used together.
Bison is a parser-generator. Its input is a file where you have written a grammar that describes the syntax of a language, and Bison generates a parser. The parser (or "syntactical analyzer") is the part of a compiler (or similar tool) that analyzes input according to the syntax of the language. For example, it is the parser that knows that an if statement can, but doesn't have to, have an else part.
Flex is a scanner-generator, and from a file with regular expressions it creates a scanner. The scanner (or "lexical analyzer") is the part of a compiler (or similar tool) that analyzes input and divides it up into "tokens". A token can be a keyword such as if, an operator such as +, an integer constant, etcetera. It is the scanner that for example knows that an integer constant is written as a sequence of one or more digits.
The scanner reports to the parser when it has found a token. For example, if the input starts with 123, the scanner might recognize that this is an integer constant, and report this to the parser. In the case of Flex and Bison, it does this by returning the token code for integer constant, which might (just as an example) be 17. But since the scanner and parser must agree on these token codes, they need common definitions. Bison will generate token codes, and if given the flag -d it will output them in a .h file.
Thomas Niemann's A Compact Guide to Lex & Yacc gives a good introduction to how to use Flex and Bison. (Lex and Yacc are the old, original tools, and Flex and Bison are new, free versions of the same tools.)
For yacc and lex part this error disappeared for me when I used yacc -d xyz.y command where d is flag and xyz is file of my yacc file.

lex flex scanner with multiple buffers

I want to use the yy_scan_bytes() as I have null characters defining a rule. My problem is that my string can match more than one rule. I want to get hold of all the rules matched. I want to feed the yylex() function one character at a time and check if something matched. I tried the following code for testing but this doesnt work.
for(int i=0;i<length;i++)
{
yy_scan_bytes(&temp[i],1 );
index=TomsonTalkslex();
}
For simplicity I just return the index of the rule matched from scanner. temp is a char buffer. I tried to use the yy_switch_to_buffer(yy_scan_bytes(&temp[i],1 )); but this didnt work.
How can I tell the scanner not to reset its state and continue processing subsequent buffers with the same state.
Ok, This is just a misunderstanding of how lex/flex works. By default, yylex hooks into stdin, reading until it receives EOF, and matching each rule. That's why it's a tokenizer. So, the sample program below will read from stdin until you enter -c to send an EOF.
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
ab { fprintf(yyout, "We ran the ab rule.\n"); }
cd { fprintf(yyout, "We ran the cd rule.\n"); }
// echo everything else we find to yyout
. { ECHO; }
\n { ECHO; }
%%
To compile the above, use:
flex -Cf scanner.l
gcc -O -o flexer.exe scanner.c
Save the source file as scanner.l when you do this. Once you compile, you will get a file called flexer.exe in the same directory. Run it from a terminal, and you will get a blank prompt waiting for input. Everything you type will try and match against the rules, until you find only one match. It will then execute the code associated with the rule.
Therefore, if you type abcd, then you will match both the ab and cd rules.
I suggest reading lex and yacc for a more detailed introduction.

How do I show the value of a #define at compile-time?

I am trying to figure out what version of Boost my code thinks it's using. I want to do something like this:
#error BOOST_VERSION
but the preprocessor does not expand BOOST_VERSION.
I know I could print it out at run-time from the program, and I know I could look at the output of the preprocessor to find the answer. I feel like having a way of doing this during compilation could be useful.
I know that this is a long time after the original query, but this may still be useful.
This can be done in GCC using the stringify operator "#", but it requires two additional stages to be defined first.
#define XSTR(x) STR(x)
#define STR(x) #x
The value of a macro can then be displayed with:
#pragma message "The value of ABC: " XSTR(ABC)
See: 3.4 Stringification in the gcc online documentation.
How it works:
The preprocessor understands quoted strings and handles them differently from normal text. String concatenation is an example of this special treatment. The message pragma requires an argument that is a quoted string. When there is more than one component to the argument then they must all be strings so that string concatenation can be applied. The preprocessor can never assume that an unquoted string should be treated as if it were quoted. If it did then:
#define ABC 123
int n = ABC;
would not compile.
Now consider:
#define ABC abc
#pragma message "The value of ABC is: " ABC
which is equivalent to
#pragma message "The value of ABC is: " abc
This causes a preprocessor warning because abc (unquoted) cannot be concatenated with the preceding string.
Now consider the preprocessor stringize (Which was once called stringification, the links in the documentation have been changed to reflect the revised terminology. (Both terms, incidentally, are equally detestable. The correct term is, of course, stringifaction. Be ready to update your links.)) operator. This acts only on the arguments of a macro and replaces the unexpanded argument with the argument enclosed in double quotes. Thus:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
will assign identical values to s1 and s2. If you run gcc -E you can see this in the output. Perhaps STR would be better named something like ENQUOTE.
This solves the problem of putting quotes around an unquoted item, the problem now is that, if the argument is a macro, the macro will not be expanded. This is why the second macro is needed. XSTR expands its argument, then calls STR to put the expanded value into quotes.
BOOST_PP_STRINGIZE seems a excellent solution for C++, but not for regular C.
Here is my solution for GNU CPP:
/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))
Above definitions result in:
test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"
For "defined as interger", "defined as string", and "defined but no value" variables , they work just fine. Only for "not defined" variable, they displayed exactly the same as original variable name. You have to used to it -- or maybe someone can provide a better solution.
If you are using Visual C++, you can use #pragma message:
#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))
Edit: Thanks to LB for link
Apparently, the GCC equivalent is (not tested):
#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)
As far as I know '#error' only will print strings, in fact you don't even need to use quotes.
Have you tried writing various purposefully incorrect code using "BOOST_VERSION"? Perhaps something like "blah[BOOST_VERSION] = foo;" will tell you something like "string literal 1.2.1 cannot be used as an array address". It won't be a pretty error message, but at least it'll show you the relevant value. You can play around until you find a compile error that does tell you the value.
Without boost :
define same macro again and compiler HIMSELF will give warning.
From warning you can see location of the previous definition.
vi file of previous definition .
ambarish#axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition
#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666
int main ()
{
}
In Microsoft C/C++, you can use the built-in _CRT_STRINGIZE() to print constants. Many of my stdafx.h files contain some combination of these:
#pragma message("_MSC_VER is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION))
and outputs something like this:
_MSC_VER is 1915
_MFC_VER is 0x0E00
_ATL_VER is 0x0E00
WINVER is 0x0600
_WIN32_WINNT is 0x0600
_WIN32_IE is 0x0700
NTDDI_VERSION is 0x06000000
#define a <::BOOST_VERSION>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::106200': No such file or directory
Pros:
Works on builtin macroses
Works even if preprocess to file is enabled, even if invalid tokens are present:
#define a <::'*/`#>
#include a
MSVC2015: fatal error C1083: Cannot open include file: '::'*/`#': No such file or directory
GCC4.x: warning: missing terminating ' character [-Winvalid-pp-token]
#define a <::'*/`#>
Cons:
Sometime fails because of invalid characters in the include file path. Can be fixed by change a prefix (see update section below).
Update:
For GCC 4.7.x and lower the output throws the error:
error: #include expects "FILENAME" or <FILENAME>
To fix that you can change the prefix:
#define a <.__cplusplus>
#include a
fatal error: .201103L: No such file or directory
You could also preprocess the source file and see what the preprocessor value evaluates to.
You could write a program that prints out BOOST_VERSION and compile and run it as part of your build system. Otherwise, I think you're out of luck.
Are you looking for
#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif
Not great if BOOST_VERSION is a string, like I've assumed, but there may also be individual integers defined for the major, minor and revision numbers.
Looking at the output of the preprocessor is the closest thing to the answer you ask for.
I know you've excluded that (and other ways), but I'm not sure why. You have a specific enough problem to solve, but you have not explained why any of the "normal" methods don't work well for you.
BOOST_VERSION is defined in the boost header file version.hpp.
Take a look at the Boost documentation as well, regarding how you are using the macro:
In reference to BOOST_VERSION, from http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macros:
Describes the boost version number in
XXYYZZ format such that:
(BOOST_VERSION % 100) is the sub-minor
version, ((BOOST_VERSION / 100) %
1000) is the minor version, and
(BOOST_VERSION / 100000) is the major
version.
Instead of #error, try redefining the macro, just before it is being used. Compilation will fail and compiler will provide the current value it thinks applies to the macro.
#define BOOST_VERSION blah