在 Ubuntu 中,gcc 报告在 macOS 中未报告的函数声明错误
In Ubuntu gcc reports function declaration errors that did not report in macOS
我正尝试与队友一起使用 lex 和 yacc 构建一个简单的语言编译器。在我的 macOS 上一切顺利,但是在 win10 和 Ubuntu gcc 中报告错误。
起初我在我的 parser.y
中包含 "lex.yy.c"
,并且 解决了 multiple definition of main()
的错误,但是更多的错误和警告被更改:
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);
我运行thirf命令后出现三个命令和错误
yacc -v -d parser.y
lex lexer.l
gcc -Wall -o example y.tab.c lex.yy.c
gcc 和 Ubuntu 版本:gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
最小的例子是:
- 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(.nd,"P");head=$$.nd;}
;
S : ID EQ F {.nd=mknode("ID");.nd=mknode("=");
addBro(.nd,.nd);addBro(.nd,.nd);
$$.nd = addKid(.nd,"S");}
;
F :ID {.nd=mknode("ID");
$$.nd=addKid(.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(.nd,.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;
}
输入文件in.in
:
a=b
查看警告。 .
您的代码以此开头:
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*);
| ^~~~
此处声明的 struct node
是该函数声明的局部变量,不同于其他地方声明的任何 struct node
,因此通常是无用的。这正是 C 标准所说的。
解决方法:添加一行
struct node;
在函数声明之前。
我正尝试与队友一起使用 lex 和 yacc 构建一个简单的语言编译器。在我的 macOS 上一切顺利,但是在 win10 和 Ubuntu gcc 中报告错误。
起初我在我的 parser.y
中包含 "lex.yy.c"
,并且 multiple definition of main()
的错误,但是更多的错误和警告被更改:
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);
我运行thirf命令后出现三个命令和错误
yacc -v -d parser.y
lex lexer.l
gcc -Wall -o example y.tab.c lex.yy.c
gcc 和 Ubuntu 版本:gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
最小的例子是:
- 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(.nd,"P");head=$$.nd;}
;
S : ID EQ F {.nd=mknode("ID");.nd=mknode("=");
addBro(.nd,.nd);addBro(.nd,.nd);
$$.nd = addKid(.nd,"S");}
;
F :ID {.nd=mknode("ID");
$$.nd=addKid(.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(.nd,.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;
}
输入文件in.in
:
a=b
查看警告。
您的代码以此开头:
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*);
| ^~~~
此处声明的 struct node
是该函数声明的局部变量,不同于其他地方声明的任何 struct node
,因此通常是无用的。这正是 C 标准所说的。
解决方法:添加一行
struct node;
在函数声明之前。