Thread: old c compiler project

  1. #1
    Registered User
    Join Date
    Aug 2023
    Posts
    45

    Post old c compiler project

    In this old c code it would not compile. I did change the old style main() parameter listing to the newer form. Then I noticed that there several functions being called before they were defined so I cut and pasted in function prototypes before main()! Still work to do. The compiler complained about missing libraries so I added in the appropriate headers and now the project compiles and actually runs.
    In the code line
    BOOLEAN get_source_line();
    the compiler gives the following warning messages:

    [Warning] empty parentheses were disambiguated as a function declaration [-Wvexing-parse]

    [Note] remove parentheses to default-initialize a variable
    [Note] or replace parentheses with braces to value-initialize a variable
    Anyone know what this is about?
    Attached Files Attached Files
    Last edited by maxcy; 08-11-2023 at 05:25 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Filenames in capitals (especially the .C bit) are assumed to be C++ programs.

    Code:
    $ gcc LIST.C 
    LIST.C:63:1: warning: ISO C++ forbids declaration of ‘main’ with no type [-Wreturn-type]
       63 | main(int argc, char** argv)
          | ^~~~
    LIST.C: In function ‘int main(int, char**)’:
    LIST.C:65:28: warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
       65 |     BOOLEAN get_source_line();
          |                            ^~
    LIST.C:65:28: note: remove parentheses to default-initialize a variable
       65 |     BOOLEAN get_source_line();
          |                            ^~
          |                            --
    LIST.C:65:28: note: or replace parentheses with braces to value-initialize a variable
    If you force the compiler to treat it as a C program, this happens.
    Code:
    $ gcc -x c LIST.C 
    LIST.C:23:10: fatal error: cstring: No such file or directory
       23 | #include <cstring>
          |          ^~~~~~~~~
    compilation terminated.
    Fixing your C++ headers to be C headers, you're almost there.
    Code:
    $ gcc -x c LIST.C 
    LIST.C:63:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
       63 | main(int argc, char** argv)
          | ^~~~
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User Sir Galahad's Avatar
    Join Date
    Nov 2016
    Location
    The Round Table
    Posts
    277
    Quote Originally Posted by maxcy View Post
    In this old c code it would not compile. I did change the old style main() parameter listing to the newer form. Then I noticed that there several functions being called before they were defined so I cut and pasted in function prototypes before main()! Still work to do. The compiler complained about missing libraries so I added in the appropriate headers and now the project compiles and actually runs.
    In the code line
    BOOLEAN get_source_line();
    the compiler gives the following warning messages:

    [Warning] empty parentheses were disambiguated as a function declaration [-Wvexing-parse]

    [Note] remove parentheses to default-initialize a variable
    [Note] or replace parentheses with braces to value-initialize a variable
    Anyone know what this is about?
    Those strcpy calls are buffer-overflows just waiting to happen. Save yourself the headache and use strncpy.

    The program should not segfault when called without arguments either. Print a "usage" message and exit with a non-zero value.

    The "levels" variable is also never used, so it will always be zero. (I presume the original author was planning on counting indention levels but never actually finished implementing the feature?) So that could be removed from the program entirely.

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Adding to what Salem and Galahad have said:

    You are mixing tabs and spaces for indentation. Just use one or the other. Spaces are best.

    Not only should you check that argc is 2 to ensure a parameter has been provided, you should also check that the FILE* is not NULL after trying to open the file.

    No need to strcpy argv[1] to another buffer. If you want a better name for it, just do:
    const char *source_name = argv[1];

    No need to copy the 'source_buffer' to the 'print_buffer' just to add the line number. Just print the line number before the line in the printf statement.

    The whole 'save_ch', 'save_chp' thing is not well thought out. If the line is too long the printf("%s", line) call will not print a newline (left in the buffer by the fgets). Also, the rest of the line is just thrown away.

    The 'while (get_source_line()) ;' structure is kind of dumb and part of the reason there are so many globals. It would probably be better to put the whole program in main.

    The "BOOLEAN get_source_line();" problem is caused by having that declaration in main for no purpose (and compiling it as C++). Just remove it.

    Here's a rewrite. Still not perfect, though.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
     
    #define MAX_SOURCE_LINE 1024
    #define MAX_PRINT_LINE    74  // leave room for line number
    #define MAX_DATE_STRING   32
    #define LINES_PER_PAGE    50
     
    int main(int argc, char **argv) {
        if (argc != 2) {
            fprintf(stderr, "Usage: lister SOURCE_FILE");
            exit(EXIT_FAILURE);
        }
     
        const char *source_name = argv[1];
     
        FILE *file = fopen(source_name, "r");
        if (!file) {
            perror("Error: cannot open file");
            exit(EXIT_FAILURE);
        }
     
        char date[MAX_DATE_STRING];
        time_t timer;
        time(&timer);
        strcpy(date, asctime(localtime(&timer)));
     
        char buffer[MAX_SOURCE_LINE];
        int line_number = 0;
        int page_number = 0;
        int line_count  = LINES_PER_PAGE;
     
        while (fgets(buffer, MAX_SOURCE_LINE, file) != NULL) {
            buffer[strcspn(buffer, "\r\n")] = '\0'; // remove newline
     
            ++line_number;
     
            if (++line_count > LINES_PER_PAGE) {
                printf("\fPage %d   %s   %s\n\n",
                   ++page_number, source_name, date);
                line_count = 1;
            }
     
            char *out = buffer;
            int len = strlen(buffer);
     
            if (len == 0) {
                printf("%4d:\n", line_number);
                continue;
            }
     
            while (len > 0) {
                char save_ch = '\0';
                if (len > MAX_PRINT_LINE) {
                    save_ch = out[MAX_PRINT_LINE];
                    out[MAX_PRINT_LINE] = '\0';
                }
     
                if (out == buffer)
                    printf("%4d: %s\n", line_number, out);
                else
                    printf("      %s\n", out);
     
                if (len < MAX_PRINT_LINE)
                    len = 0;
                else {
                    out[MAX_PRINT_LINE] = save_ch;
                    out += MAX_PRINT_LINE;
                    len -= MAX_PRINT_LINE;
                }
            }
        }
     
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #5
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    In c code are function prototypes/declarations needed in the header file. The .c file does contain the function definitions, but what about the declarations in the header? I know they are definitely needed in C++ code.
    maxcy/wt1v

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Prototypes are only necessary in C source code for forward declaration purposes only.

    If you arrange code in bottom up order (main is last), you only ever need a prototype for weird mutual recursion cases.

    But having all the prototypes at the start of the source file anyway is a useful documentation overview of what's in the rest of the file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    In this particular project that I am currently working on, the code has all the functions (lots of them) defined after the main(). To make matters worst, after much checking around, I found that some of the function definitions contained references to other functions that have not been defined or declared yet, but are found later on in the code! So I did put in the function prototypes before main() and since I was doing that I put all the function prototypes there also. And yes, it is nice to see a record of all the functions in this project listed at the top of the file.
    maxcy / wt1v

  8. #8
    Registered User
    Join Date
    Aug 2023
    Posts
    45

    bad book code

    old c compiler project-get_source_line-pngold c compiler project-globals-pngold c compiler project-main-png
    Still working on this project. In the get_source_line function there is an external that will not compile (get_source_line.png). I commented out this line and added in the commented line and it compiles so something is wrong with the external. Checking through all the files I find that FILE is not used! A big error in the code!! Checking further into the books folders I found that the FILE* codefile was used later so I changed main() with a global declaration (globals.png) and then added in the new version of main() code to open the file(main.png) Now the compiler doesn't like FILE, which is an enumerated type! (TOKEN_CODE.png). It expects an expression before FILE! Comment out the FILE enum and it compiles! I know FILE is part of the stdlib, but what has that got to do with the enum?
    maxcy / wt1v
    Attached Images Attached Images old c compiler project-token_code-png 

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Because FILE is properly declared in stdio.h, and is the standard type name to hold information about files opened within the program.

    How much C do you know?

    Taking 30+ year old C from pre-ANSI days and trying to drag it into the 21st century is a "cleaning the Augean stables" type task.

    Lastly, copy/paste the raw text from your IDE.
    Fuzzy pictures are useless to refer to or comment on.

    For example, the fgets() in the first picture is referring to a file handle that no longer? exists.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    I love your metaphor, I actually had to google it to know your meaning was! My only remaining problem with compiling this code is the FILE error. The fgets line has nothing to do with the compiler error. Because I added in the library and the code using FILE to open a file, (the author forgot to open the file!) and since this is a c compiler book, the enum for rw[] contains a keyword (FILE) for the scanner to search for. This keyword is a typedef elsewhere in this compiler project. So now that I fixed the opening a file code using FILE, the compiler gets confused about this word in the rw[] enum as shown and the FILE type in the library. Compilers use keywords as needed and do not care about some library already using it. If the scanner uses FILE, there must be some way to get the scanner to compile! I'm much better doing assembly code than c, but I do dabble in several other languages: C++, asm, c, LabVIEW and design patterns. So I am not a total beginner. Just stubborn at resurrecting old code! maxcy

  11. #11
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Post a link to a zipfile of all the code in the project on a site like: file.io - Super simple file sharing
    A little inaccuracy saves tons of explanation. - H.H. Munro

  12. #12
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    https://file.io/8qE2ozPEE6fg
    a link to all the code in my project


  13. #13
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    I do hope this method of file sharing works as I have never used it before!

  14. #14
    Registered User
    Join Date
    Aug 2023
    Posts
    45
    Now that all my project files can be seen, let me reiterate the problem: in scanner.h there is an enum, FILE, defined in the TOKEN-CODE TYPEDEF. This is used throughout the project. Also, in calc.c I am opening a file via argv[1] that returns code_file which is of type FILE via a library. The compiler gives an error about FILE being use twice even though anyone can see the difference between an enum and a file type from the library. That is what seems to be the final remaining problem with getting this code to compile! It is a fairly large project.
    maxcy

  15. #15
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Is this from 1991, Ronald Mak, Writing Compilers and Interpreters, 3rd edition?

    Is this even supposed to compile?
    I get about 6 errors and 200 warnings.
    I notice in the top comment of calc.c:
    /* see compiler2.c chapter 14 for extern FILE fix! */
    And in the top comment of scanner.c
    /* line 75 col 47 [Error] expected expression before 'FILE' */

    FILE has been used as an enum constant, which seems kind of idiotic.
    Maybe you should change the enum to FILE2.

    EDIT: This basically compiles: https://file.io/oaKiSk5HQXOS
    Last edited by john.c; 08-19-2023 at 10:15 AM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 01-28-2016, 02:43 PM
  2. Replies: 4
    Last Post: 08-02-2013, 06:45 PM
  3. Replies: 5
    Last Post: 02-23-2013, 03:37 PM
  4. Replies: 2
    Last Post: 02-04-2008, 02:34 AM
  5. your 11th & 12th grade c++ project or similar project
    By sleepyheadtony in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 01-13-2002, 05:14 PM

Tags for this Thread