Home > Software engineering >  In Ubuntu gcc reports function declaration errors that did not report in macOS
In Ubuntu gcc reports function declaration errors that did not report in macOS

Time:05-22

I am trying to build a simple language compiler using lex and yacc with my teammate. Everything goes well on my macOS, however in win10 and Ubuntu gcc reported errors.
At first I include "lex.yy.c" in my parser.y, and in this answer the error that multiple definition of main() is solved, however more errors and warnings altered:

ask.y:80:6: error: conflicting types for 'addBro'
void addBro( struct node *Leftbro, struct node *Rightbro) {     
     ^
ask.y:13:10: note: previous declaration is here
    void addBro( struct node *Leftbro, struct node *Rightbro);
         ^
ask.y:84:6: error: conflicting types for 'printTree'
void printTree(struct node *n, int type,  int level)
     ^
ask.y:11:7: note: previous declaration is here
        void printTree(struct node *tree, int type,  int level);  

I run three commands and errors occurred after the thirf command

  1. yacc -v -d parser.y
  2. lex lexer.l
  3. gcc -Wall -o example y.tab.c lex.yy.c

The gcc and Ubuntu version: gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

The minimal example are:

  1. parser.y:
%{
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<ctype.h>
    #define COUNT 5
    void yyerror(const char *s);
    int yylex();
    int yywrap();
    void printtree(struct node*);
    void printTree(struct node *tree, int type,  int level);  
    
    void addBro( struct node *Leftbro, struct node *Rightbro);
    struct node* mknode( char *token);
    struct node* addKid( struct node *kid,char *token);

    int count=0;
    int q;
    char type[10];
    extern int countn;
    struct node *head;
    struct node { 
        struct node *firstKid;
        struct node *rightBro;
        char *token; 
    };
%}

%union { 
    struct var_name { 
        char name[100]; 
        struct node* nd;
    } nd_obj; 
} 

%start P
%token <nd_obj> EQ  SEMI ID
// NUMBER
%type <nd_obj> P  S F

%%
/* descriptions of expected inputs     corresponding actions (in C) */
P       : S                     {$$.nd = addKid($1.nd,"P");head=$$.nd;}
;
S       : ID EQ F               {$1.nd=mknode("ID");$2.nd=mknode("=");
                                addBro($3.nd,$2.nd);addBro($2.nd,$1.nd);
                                $$.nd = addKid($3.nd,"S");}
;
F       :ID                     {$1.nd=mknode("ID");
                                $$.nd=addKid($1.nd,"F");}                                                             
;
%%                     /* C code */

int main() {
    yyparse();
    //printtree(head); 
    printTree(head,0,0);
    printf("\n\n");
}

struct node* addKid( struct node *kid,char *token) {    
    struct node *newnode = (struct node *)malloc(sizeof(struct node));
    char *newstr = (char *)malloc(strlen(token) 1);
    strcpy(newstr, token);
    newnode->firstKid = kid;
    newnode->rightBro = NULL;
    newnode->token = newstr;
    return(newnode);
}
struct node* mknode( char *token) { 
    struct node *newnode = (struct node *)malloc(sizeof(struct node));
    char *newstr = (char *)malloc(strlen(token) 1);
    strcpy(newstr, token);
    newnode->firstKid = NULL;
    newnode->rightBro = NULL;
    newnode->token = newstr;
    return(newnode);
}
//addBro($2.nd,$3.nd);
void addBro( struct node *Leftbro, struct node *Rightbro) { 
    Leftbro->rightBro = Rightbro;
}

void printTree(struct node *n, int type,  int level)
{
    int i;

    if (NULL == n)
        return;

    printTree(n->rightBro, 2, level);
    switch (type)
    {
    case 0:
        printf("%2s\n", n->token);
        break;
    case 1:
        for (i = 0; i < level; i  ) 
            printf("\t");
        printf("\n");
        for (i = 0; i < level; i  ) 
            printf("\t");
        printf("%2s\n", n->token);

        break;
    case 2:

        for (i = 0; i < level; i  ) 
            printf("\t");
        printf("%2s\n", n->token);
        for (i = 0; i < level; i  ) 
            printf("\t");
        printf("\n");
        break;  
    }
    printTree(n->firstKid, 1,  level 1);
}

void yyerror(const char* msg) {
    fprintf(stderr, "%s\n", msg);
}
  1. lexer.l:
%{
    #include "y.tab.h"
    int countn=0;
%}

%option yylineno

alpha [a-zA-Z]
digit [0-9]
%%
"="    {strcpy(yylval.nd_obj.name,(yytext)); return EQ;}

{alpha}({alpha}|{digit})*   {strcpy(yylval.nd_obj.name,(yytext));  return ID; }

\/\/.*                      { ; }
\/\*(.*\n)*.*\*\/           { ; } 
[ \t]*                      { ; }
[\n]                        { countn  ; }
.                       { return *yytext; }
%%

int yywrap() {
    return 1;
}

the input file in.in:

a=b

CodePudding user response:

Look at the warnings. Always look at the warnings.

Your code starts with this:

parser.y:10:27: warning: ‘struct node’ declared inside parameter list 
will not be visible outside of this definition or declaration
   10 |     void printtree(struct node*);
      |                           ^~~~

The struct node declared here is local to this function declaration, is distinct from any struct node declared elsewhere, and thus is generally useless. This is exactly how the C standard says it should be.

Solution: add a line

struct node;

before the function declarations.

  • Related