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
yacc -v -d parser.y
lex lexer.l
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:
- 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);
}
- 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.