Building code with a self-designed C compiler - c

As a part of my college project, we're supposed to develop a C compiler. The lexer and parser part is over - the tools Flex & Bison made our uphill task much simpler. Now where we're stuck is that we are unable to move on with the project. How exactly does one proceed once we have these three files in hand:
y.tab.h
y.tab.c
lex.yy.c
We also managed to produce an executable by using the following command on the DOS prompt
gcc lex.yy.c y.tab.c -o example1
and i got the executable example.exe...
Now how to proceed to get the compiler running? How to get it to build user C code?

You should check whether your example.exe can read a C program and report any syntax errors.
If it cannot, fix your .y and/or .l files and try again.
If it can, great, you have a working parser. Now turn it into a working compiler. Keep adding code, known as semantic actions, to the .y file, implementing more and more of the compiler's functionality. First, make sure you can report semantic errors, such as invalid types or missing declarations. Then implement assembly code generation.
When the .y file becomes too big, turn some code into functions and move them to separate .c files.

Related

C Makefile exercises from HeadFirst C

I am learning C from Head First C. One short exercise is connected with Makefile. The source code is:
oggswing: oggswing.c oggswing.h
gcc oggswing.c -o oggswing
swing.ogg: whitennerdy.ogg oggswing
oggswing whitennerdy.ogg swing.ogg
(Please assume that the indented lines start with the required tab.)
I do not understand oggswing whitennerdy.ogg swing.ogg. There isn’t any command like gcc or the other. I can't find any solutions why is that correct? Could you help me?
oggswing is the result of building oggswing.c.
It can then be executed to process the two .ogg files (in whatever way it implements).
And oggswing will be built because it is a dependency for the target swing.ogg.

autoconf configure results in C std lib header related compile errors

I am attempting to build a project that comes with an automake/autoconf build system. This is a well-used project, so I'm skeptical about a problem with the configure scripts, makefiles, or code as I received them. It is likely some kind of environment, path, flag, etc problem - something on my end with simply running the right commands with the right parameters.
The configuration step seems to complete in a satisfactory way. When I run make, I'm shown a set of errors primarily of these types:
error: ‘TRUE’ undeclared here (not in a function)
error: ‘struct work’ has no member named ‘version’
error: expected ‘)’ before ‘PRIu64’
Let's focus on the last one, which I have spent time researching - and I suspect all the errors are related to missing definitions. Apparently the print-friendly extended definitions from the C standard library header file inttypes.h is not being found. However, in the configure step everything is claimed to be in order:
configure:4930: checking for inttypes.h
configure:4930: /usr/bin/x86_64-linux-gnu-gcc -c -g -O2 conftest.c >&5
configure:4930: $? = 0
configure:4930: result: yes
All the INTTYPES flags are set correctly if I look in confdefs.h, config.h, config.log Output Variables, etc:
HAVE_INTTYPES_H='1'
#define HAVE_INTTYPES_H 1
The problem is the same whether doing a native build, or cross-compiling (for arm-linux-gnueabihf, aka armhf).
The source .c file in question does have config.h included as you'd expect, which by my understanding via the m4 macros mechanic should be adding an
#include <inttypes.h>
line. Yes, as you may be inclined to ask, if I enter this line myself into the .c file it appears to work and the PRIu64 errors go away.
I'm left with wondering how to debug this type of problem - essentially, everything I am aware of tells me I've done the configure properly, but I'm left with a bogus make process. Aside from trying every ./configure tweak and trick I can find, I've started looking at the auto-generated Makefile.in itself, but nothing so far. Also looking into how I can get the C pre-processor to tell me which header files it's actually inserting.
EDIT: I've confirmed that the -DHAVE_CONFIG_H mechanic looks good through configure, config.log, Makefile, etc.
autoconf does not automatically produce #include directives. You need to do that on your own based on the HAVE_* macros. So you'll have to add something like this:
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
If these lines show up in confdefs.h, a temporary header file used by configure scripts, this does excuse your application from performing these #includes. If configure writes them to confdefs.h, this is solely for the benefit of other configure tests, and not for application use.
First, run make -n for the target that failed. This is probably some .o file; you may need some tweaking to get its path correctly.
Now you have the command used to compile your file. If you don't find the problem by meditating on this command, try to run it, adding the -E to force preprocessor output text instead of invoking the compiler.
Note that now the .o file will be text, and you must rebuild it without -E later.
You may find some preprocessor flags useful to get more details: -dM or -dD, or others.

How come when I try to compile my C program by making a file named for the program it creates an application for it?

I once tried to compile a C program I made that was for a chess game (thanks to YouTube's Bluefever Software for the tutorial), but when I went to compile the program, I executed this line of code:
C:\TDM-GCC-64\>gcc Chess/chess.c Chess/init.c -o chess
The compiling worked (there were no syntax errors or anything), but when I got to my file directory, I saw this (circled in blue):
An unexpected application (but there were no viruses!):
How did this happen? It may had something to do with the line I was compiling, but what is the "intel" behind this?
It is normal for the compiler to generate an application!
What is surprising is the location for the executable, it should have been generated in the parent directory:
C:\TDM-GCC-64\> gcc Chess/chess.c Chess/init.c -o chess
The explanation is interesting:
You are using the Windows operating system, where the filenames are case insensitive.
You instructed gcc to generate the executable into chess, but this is the name of the Chess directory. In this case, gcc generates the executable in the named directory and gives it a name that is the basename of the first source file chess.c -> chess.
Furthermore, the application name really is chess.exe in Windows, but the default setting for the file manager is to not display file extensions. This is a very unfortunate choice. I suggest you change this setting in the Windows/File Explorer Options window to always show file extensions. This will allow you to distinguish chess.c, chess.exe and chess.h more easily.
You have a Makefile in the Chess directory, you should use the make command to build the executable:
C:\TDM-GCC-64\> make -C Chess
Or simply cd to the Chess subdirectory and type:
C:\TDM-GCC-64\Chess> make
That's the file you told the compiler to make.
The -o option to gcc is the output file. In this case, you told it to create an executable file named chess. And that's exactly what was created.
The compiler is automatically creating an executable file while compiling.

Error compiling gold in binutils

I am trying to compile the project KernelGen (http://hpcforge.org/plugins/mediawiki/wiki/kernelgen/index.php/Compiling) for some research project I am doing , the build script is using rpmbuild and it looks like it has a dependency on gold from binutils. Build keeps failing when trying to compile gold with the following error:
/bin/sh ./../ylwrap yyscript.y y.tab.c yyscript.c y.tab.h yyscript.h y.output yyscript.output -- byacc -d
byacc: e - line 42 of "/home/xxx/rpmbuild/BUILD/binutils-2.23.2/gold/yyscript.y", syntax error
%pure-parser
^
The file yyscript.c looks like this:
/* We need to use a pure parser because we might be multi-threaded.
We pass some arguments through the parser to the lexer. */
%pure-parser
%parse-param {void* closure}
%lex-param {void* closure}
/* Since we require bison anyhow, we take advantage of it. */
%error-verbose
/* The values associated with tokens. */
It looks like it is some kind of grammar file that fails to parse. Things is this file is from the binutils package itself and I can't find a reason why it is failing to parse.
Any ideas ?
Your version of byacc doesn't properly support %pure-parser, which I believe was originally a bison extension. Use bison instead.

Trying to adapt existing c project to CUDA, .cu files not found by Makefile

I'm trying to accelerate a key function in a c project (not c++) using CUDA.
For some reason, i can't get the Makefile's to recognise the .cu extension when I change the name of one of the files to .cu.
It's using a configure script and .am/.in/.deps files, which I don't really understand all that well, but basically I grepped references to file.c and changed them all to file.cu, but it produces a file.o: File Not Found error.
Top level make file
https://www.dropbox.com/s/g282qvbdu8pdas0/Makefile
Src folder makefile
https://www.dropbox.com/s/b4pq026od8gauqi/Makefile
The search command I used was
grep -R -i "file.c"
and I simply changed them all to file.cu, then re-ran configure, make clean, make all - result is File Not Found.
I suppose it must be something to do with extensions being ignored/accepted by the Makefile, but as it's been a long time since I've programmed in C and I've never used such complex Makefiles I don't know how to fix it.
Any ideas?
*PS Also, file.cu has compile errors at the moment, but the error message I'm getting is File Not Found, so I think that's not the problem.
You need to have a rule to build o file from a cu file:
cudafile.o: cudafile.cu
nvcc $(NVCC_FLAGS) -c %< -o $#
So you also need to specify the rule for the cu file, and use nvcc for compilation.
The following guide seems to cover it...
http://mcclanahoochie.com/blog/2011/02/automake-and-cuda/
Actually, most of the advice given in the link seems unnecessary for basic compilation, but for some reason I found that when I re-created the config file using autoconf it worked. No explanation comes to mind.

Resources