GCC 编译器错误
我已经成功编译了词法分析器和解析器,如下所示。编译 .exe 解释器的最后阶段会抛出错误。
任何有关我错过的内容的帮助或提示将不胜感激。
me@PC /cygdrive/e/HUB/Archive/spl
$ gcc -o spl.exe spl.c parser.tab.c -lfl
spl.c:4:1: warning: data definition has no type or storage class
parser.y: In function ‘yyparse’:
parser.y:145:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:147:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:149:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:156:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:158:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:160:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:165:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:170:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:177:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 4 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 5 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 4 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 5 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
词法分析器:
/* Declare Symbol Table Type and Array as imported types */
%{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
%}
delim [ \t\n\r]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+
charconst "'"{letter}"'"
%%
int k;
{ws} ; /* white space, do nothing */
ENDP return(ENDP);
OF return(OF);
TYPE return(TYPE);
CODE return(CODE);
";" return(SEMICOLON);
IF return(IF);
ENDIF return(ENDIF);
THEN return(THEN);
ELSE return(ELSE);
WHILE return(WHILE);
ENDWHILE return(ENDWHILE);
DO return(DO);
ENDDO return(ENDDO);
DECLARATIONS return(DECLARATIONS);
CHARACTER return(CHARACTER);
INTEGER return(INTEGER);
REAL return(REAL);
FOR return(FOR);
ENDFOR return(ENDFOR);
IS return(IS);
BY return(BY);
TO return(TO);
WRITE return(WRITE);
NEWLINE return(NEWLINE);
READ return(READ);
NOT return(NOT);
AND return(AND);
OR return(OR);
"=" return(ASSIGNMENT);
"->" return(OUTPUTTO);
{id} return(ID);
{number} {
/* call the library function to convert ascii to int */
/* assign the integer value of the text in yytext to
the iVal part of the yylVal object */
yylval.iVal = atoi(yytext) ;
return(NUMBER);
}
{charconst} return(CHARCONST);
"+" return(PLUS);
"-" return(MINUS);
"<" return(LT);
">" return(GT);
"<>" return(BETWEEN);
"<=" return(LESSEQUAL);
">=" return(GREATEREQUAL);
"." return(POINT);
"," return(COMMA);
"/" return(DIVIDE);
"*" return(MULTIPLY);
"(" return(BRA);
")" return(KET);
":" return(COLON);
%%
/* Here is the code for the library of symbol table routines */
/* code for a simple symbol table, which is an array of pointers to
structs, each of which contains an identifier.
*/
SYMTABNODEPTR newSymTabNode()
{
return ((SYMTABNODEPTR)malloc(sizeof(SYMTABNODE)));
}
/* Look up an identifier in the symbol table, if its there return
its index. If its not there, put it in the end position,
as long as the table isn't full, and return its index.
*/
int installId(char *id)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int index;
index = lookup(id);
if (index >= 0)
{
return (index);
}
else
{
symTab[currentSymTabSize] = newSymTabNode();
strcpy(symTab[currentSymTabSize]->identifier,id);
return(currentSymTabSize++);
}
}
int lookup(char *s)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int i;
for(i=0; i<currentSymTabSize; i++)
{
if(strcmp(s,symTab[i]->identifier) == 0)
{
return (i);
}
}
return (-1);
}
解析器:
%{
/* Import the standard C I/O libraries */
#include <stdio.h>
#include <stdlib.h>
/* A Named constant denoting a null value in the tree */
#define NOTHING -1
/* These constants are used later in the code */
#define SYMTABSIZE 50
#define IDLENGTH 15
#define NOTHING -1
#define INDENTOFFSET 2
enum ParseTreeNodeType { value, expression, constant, number_constant, term } ;
/* Add more types here, as more nodes added to tree */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
/* Define the Object Structure for a tree node to store
the compiled result */
struct treeNode
{
int item;
int nodeIdentifier;
struct treeNode *first;
struct treeNode *second;
struct treeNode *third;
};
typedef struct treeNode TREE_NODE;
typedef TREE_NODE *TERNARY_TREE;
int evaluate(TERNARY_TREE);
TERNARY_TREE create_node(int,int,TERNARY_TREE,TERNARY_TREE,TERNARY_TREE);
// Symbol table def
struct symTabNode {
char identifier[IDLENGTH];
};
typedef struct symTabNode SYMTABNODE;
typedef SYMTABNODE *SYMTABNODEPTR;
SYMTABNODEPTR symTab[SYMTABSIZE];
int currentSymTabSize = 0;
%}
%start program
%union
{
int iVal;
TERNARY_TREE tVal;
}
%token<iVal> PLUS MINUS MULTIPLY DIVIDE BRA KET CHARCONST ENDP OF TYPE CODE
SEMICOLON IF ENDIF THEN ELSE WHILE ENDWHILE DO ENDDO DECLARATIONS CHARACTER
INTEGER REAL FOR ENDFOR IS BY TO WRITE NEWLINE READ NOT AND OR LT GT BETWEEN
LESSEQUAL GREATEREQUAL COMMA POINT COLON ASSIGNMENT OUTPUTTO
ID NUMBER
%type<tVal> value expression constant number_constant term
%%
program : ID COLON block ENDP ID POINT
;
block : CODE statement_list
| DECLARATIONS declaration_block CODE statement_list
;
declaration_block : id_list OF TYPE type SEMICOLON
| declaration_block id_list OF TYPE type SEMICOLON
;
id_list : ID
| ID COMMA id_list
;
type : CHARACTER
| INTEGER
| REAL
;
statement_list : statement
| statement_list SEMICOLON statement
;
statement_lists : statement
| statement_list SEMICOLON statement
;
statement : assignment_statement
| if_statement
| do_statement
| while_statement
| for_statement
| write_statement
| read_statement
;
assignment_statement : expression OUTPUTTO ID
;
if_statement : IF conditional THEN statement_lists ENDIF
| IF conditional THEN statement_lists ELSE statement_list ENDIF
;
do_statement : DO statement_list WHILE conditional ENDDO
;
while_statement : WHILE conditional DO statement_list ENDWHILE
;
for_statement : FOR ID IS expression BY expressions TO expression DO statement_list ENDFOR
;
write_statement : WRITE BRA output_list KET
| NEWLINE
;
read_statement : READ BRA ID KET
;
output_list : value
| value COMMA output_list
;
condition : expression comparator expression
;
conditional : condition
| NOT conditional
| condition AND conditional
| condition OR conditional
;
comparator : ASSIGNMENT
| BETWEEN
| LT
| GT
| LESSEQUAL
| GREATEREQUAL
;
expression : term
{ $$ = create_node($1,term,NULL,NULL,NULL); }
| term PLUS expression
{ $$ = create_node(NOTHING,PLUS,$1,$3); }
| term MINUS expression
{ $$ = create_node(NOTHING,MINUS,$1,$3); }
;
expressions : term
| term PLUS expressions
| term MINUS expressions
;
term : value
{ $$ = create_node($1,term,NULL,NULL,NULL); }
| value MULTIPLY term
{ $$ = create_node(NOTHING,MULTIPLY,$1,$3); }
| value DIVIDE term
{ $$ = create_node(NOTHING,DIVIDE,$1,$3); }
;
value : ID
{ $$ = create_node($1,ID,NULL,NULL,NULL); }
| constant
{ $$ = create_node($1,constant,NULL,NULL,NULL); }
| BRA expression KET
{ $$ = create_node(NOTHING,BRA,$2,NULL,NULL); }
;
constant : number_constant
{ $$ = create_node($1,number_constant,NULL,NULL,NULL); }
| CHARCONST
{ $$ = create_node($1,CHARCONST,NULL,NULL,NULL); }
;
number_constant : NUMBER
{ $$ = create_node($1,NUMBER,NULL,NULL,NULL); }
| MINUS NUMBER
{ $$ = create_node(NOTHING,MINUS,$2,NULL,NULL); }
| NUMBER POINT NUMBER
{ $$ = create_node(NOTHING,REAL,$1,$2,$3); }
| MINUS NUMBER POINT NUMBER
{ $$ = create_node(NOTHING,MINUS,$2,$3,$4); }
;
%%
TERNARY_TREE create_node(int ival, int case_identifier, TERNARY_TREE p1, TERNARY_TREE p2, TERNARY_TREE p3)
{
TERNARY_TREE t;
t = (TERNARY_TREE)malloc(sizeof(TREE_NODE));
t->item = ival;
t->nodeIdentifier = case_identifier;
t->first = p1;
t->second = p2;
t->third = p3;
return (t);
}
int evaluate(TERNARY_TREE t)
{
if (t != NULL)
{
switch(t->nodeIdentifier)
{
case(NEWLINE) :
return(evaluate(t->first));
case(PLUS) :
return((evaluate(t->first)) + (evaluate(t->second)));
case(MULTIPLY) :
return((evaluate(t->first)) * (evaluate(t->second)));
case(BRA) :
return(evaluate(t->first));
case(NUMBER) :
return(t->item);
}
}
}
#include "lex.yy.c"
I've successfully compiled a lexer and parser, as shown below. The final stage of compiling the .exe interpreter throws the errors.
Any help or hints as to what I've missed would be greatly appreciated.
me@PC /cygdrive/e/HUB/Archive/spl
$ gcc -o spl.exe spl.c parser.tab.c -lfl
spl.c:4:1: warning: data definition has no type or storage class
parser.y: In function ‘yyparse’:
parser.y:145:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:147:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:149:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:156:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:158:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:160:5: error: too few arguments to function ‘create_node’
parser.y:47:14: note: declared here
parser.y:165:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:170:5: warning: passing argument 1 of ‘create_node’ makes integer from pointer without a cast
parser.y:47:14: note: expected ‘int’ but argument is of type ‘TERNARY_TREE’
parser.y:177:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 4 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:179:5: warning: passing argument 5 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 3 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 4 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
parser.y:181:5: warning: passing argument 5 of ‘create_node’ makes pointer from integer without a cast
parser.y:47:14: note: expected ‘TERNARY_TREE’ but argument is of type ‘int’
Lexer:
/* Declare Symbol Table Type and Array as imported types */
%{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
%}
delim [ \t\n\r]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+
charconst "'"{letter}"'"
%%
int k;
{ws} ; /* white space, do nothing */
ENDP return(ENDP);
OF return(OF);
TYPE return(TYPE);
CODE return(CODE);
";" return(SEMICOLON);
IF return(IF);
ENDIF return(ENDIF);
THEN return(THEN);
ELSE return(ELSE);
WHILE return(WHILE);
ENDWHILE return(ENDWHILE);
DO return(DO);
ENDDO return(ENDDO);
DECLARATIONS return(DECLARATIONS);
CHARACTER return(CHARACTER);
INTEGER return(INTEGER);
REAL return(REAL);
FOR return(FOR);
ENDFOR return(ENDFOR);
IS return(IS);
BY return(BY);
TO return(TO);
WRITE return(WRITE);
NEWLINE return(NEWLINE);
READ return(READ);
NOT return(NOT);
AND return(AND);
OR return(OR);
"=" return(ASSIGNMENT);
"->" return(OUTPUTTO);
{id} return(ID);
{number} {
/* call the library function to convert ascii to int */
/* assign the integer value of the text in yytext to
the iVal part of the yylVal object */
yylval.iVal = atoi(yytext) ;
return(NUMBER);
}
{charconst} return(CHARCONST);
"+" return(PLUS);
"-" return(MINUS);
"<" return(LT);
">" return(GT);
"<>" return(BETWEEN);
"<=" return(LESSEQUAL);
">=" return(GREATEREQUAL);
"." return(POINT);
"," return(COMMA);
"/" return(DIVIDE);
"*" return(MULTIPLY);
"(" return(BRA);
")" return(KET);
":" return(COLON);
%%
/* Here is the code for the library of symbol table routines */
/* code for a simple symbol table, which is an array of pointers to
structs, each of which contains an identifier.
*/
SYMTABNODEPTR newSymTabNode()
{
return ((SYMTABNODEPTR)malloc(sizeof(SYMTABNODE)));
}
/* Look up an identifier in the symbol table, if its there return
its index. If its not there, put it in the end position,
as long as the table isn't full, and return its index.
*/
int installId(char *id)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int index;
index = lookup(id);
if (index >= 0)
{
return (index);
}
else
{
symTab[currentSymTabSize] = newSymTabNode();
strcpy(symTab[currentSymTabSize]->identifier,id);
return(currentSymTabSize++);
}
}
int lookup(char *s)
{
extern SYMTABNODEPTR symTab[SYMTABSIZE];
extern int currentSymTabSize;
int i;
for(i=0; i<currentSymTabSize; i++)
{
if(strcmp(s,symTab[i]->identifier) == 0)
{
return (i);
}
}
return (-1);
}
Parser:
%{
/* Import the standard C I/O libraries */
#include <stdio.h>
#include <stdlib.h>
/* A Named constant denoting a null value in the tree */
#define NOTHING -1
/* These constants are used later in the code */
#define SYMTABSIZE 50
#define IDLENGTH 15
#define NOTHING -1
#define INDENTOFFSET 2
enum ParseTreeNodeType { value, expression, constant, number_constant, term } ;
/* Add more types here, as more nodes added to tree */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
/* Define the Object Structure for a tree node to store
the compiled result */
struct treeNode
{
int item;
int nodeIdentifier;
struct treeNode *first;
struct treeNode *second;
struct treeNode *third;
};
typedef struct treeNode TREE_NODE;
typedef TREE_NODE *TERNARY_TREE;
int evaluate(TERNARY_TREE);
TERNARY_TREE create_node(int,int,TERNARY_TREE,TERNARY_TREE,TERNARY_TREE);
// Symbol table def
struct symTabNode {
char identifier[IDLENGTH];
};
typedef struct symTabNode SYMTABNODE;
typedef SYMTABNODE *SYMTABNODEPTR;
SYMTABNODEPTR symTab[SYMTABSIZE];
int currentSymTabSize = 0;
%}
%start program
%union
{
int iVal;
TERNARY_TREE tVal;
}
%token<iVal> PLUS MINUS MULTIPLY DIVIDE BRA KET CHARCONST ENDP OF TYPE CODE
SEMICOLON IF ENDIF THEN ELSE WHILE ENDWHILE DO ENDDO DECLARATIONS CHARACTER
INTEGER REAL FOR ENDFOR IS BY TO WRITE NEWLINE READ NOT AND OR LT GT BETWEEN
LESSEQUAL GREATEREQUAL COMMA POINT COLON ASSIGNMENT OUTPUTTO
ID NUMBER
%type<tVal> value expression constant number_constant term
%%
program : ID COLON block ENDP ID POINT
;
block : CODE statement_list
| DECLARATIONS declaration_block CODE statement_list
;
declaration_block : id_list OF TYPE type SEMICOLON
| declaration_block id_list OF TYPE type SEMICOLON
;
id_list : ID
| ID COMMA id_list
;
type : CHARACTER
| INTEGER
| REAL
;
statement_list : statement
| statement_list SEMICOLON statement
;
statement_lists : statement
| statement_list SEMICOLON statement
;
statement : assignment_statement
| if_statement
| do_statement
| while_statement
| for_statement
| write_statement
| read_statement
;
assignment_statement : expression OUTPUTTO ID
;
if_statement : IF conditional THEN statement_lists ENDIF
| IF conditional THEN statement_lists ELSE statement_list ENDIF
;
do_statement : DO statement_list WHILE conditional ENDDO
;
while_statement : WHILE conditional DO statement_list ENDWHILE
;
for_statement : FOR ID IS expression BY expressions TO expression DO statement_list ENDFOR
;
write_statement : WRITE BRA output_list KET
| NEWLINE
;
read_statement : READ BRA ID KET
;
output_list : value
| value COMMA output_list
;
condition : expression comparator expression
;
conditional : condition
| NOT conditional
| condition AND conditional
| condition OR conditional
;
comparator : ASSIGNMENT
| BETWEEN
| LT
| GT
| LESSEQUAL
| GREATEREQUAL
;
expression : term
{ $ = create_node($1,term,NULL,NULL,NULL); }
| term PLUS expression
{ $ = create_node(NOTHING,PLUS,$1,$3); }
| term MINUS expression
{ $ = create_node(NOTHING,MINUS,$1,$3); }
;
expressions : term
| term PLUS expressions
| term MINUS expressions
;
term : value
{ $ = create_node($1,term,NULL,NULL,NULL); }
| value MULTIPLY term
{ $ = create_node(NOTHING,MULTIPLY,$1,$3); }
| value DIVIDE term
{ $ = create_node(NOTHING,DIVIDE,$1,$3); }
;
value : ID
{ $ = create_node($1,ID,NULL,NULL,NULL); }
| constant
{ $ = create_node($1,constant,NULL,NULL,NULL); }
| BRA expression KET
{ $ = create_node(NOTHING,BRA,$2,NULL,NULL); }
;
constant : number_constant
{ $ = create_node($1,number_constant,NULL,NULL,NULL); }
| CHARCONST
{ $ = create_node($1,CHARCONST,NULL,NULL,NULL); }
;
number_constant : NUMBER
{ $ = create_node($1,NUMBER,NULL,NULL,NULL); }
| MINUS NUMBER
{ $ = create_node(NOTHING,MINUS,$2,NULL,NULL); }
| NUMBER POINT NUMBER
{ $ = create_node(NOTHING,REAL,$1,$2,$3); }
| MINUS NUMBER POINT NUMBER
{ $ = create_node(NOTHING,MINUS,$2,$3,$4); }
;
%%
TERNARY_TREE create_node(int ival, int case_identifier, TERNARY_TREE p1, TERNARY_TREE p2, TERNARY_TREE p3)
{
TERNARY_TREE t;
t = (TERNARY_TREE)malloc(sizeof(TREE_NODE));
t->item = ival;
t->nodeIdentifier = case_identifier;
t->first = p1;
t->second = p2;
t->third = p3;
return (t);
}
int evaluate(TERNARY_TREE t)
{
if (t != NULL)
{
switch(t->nodeIdentifier)
{
case(NEWLINE) :
return(evaluate(t->first));
case(PLUS) :
return((evaluate(t->first)) + (evaluate(t->second)));
case(MULTIPLY) :
return((evaluate(t->first)) * (evaluate(t->second)));
case(BRA) :
return(evaluate(t->first));
case(NUMBER) :
return(t->item);
}
}
}
#include "lex.yy.c"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编译错误来自
$$ = create_node(NOTHING,PLUS,$1,$3);
调用,其中create_node
使用 4 个参数调用,而它期望 5 个参数。但是它们不是唯一的问题,因为还有
create_node
调用,其中第一个参数是从TERNARY_TREE
而不是整数分配的(出现时是表达式:term{. ..} 规则)。The compile errors come from the
$$ = create_node(NOTHING,PLUS,$1,$3);
calls, wherecreate_node
is called with 4 parameters, while it expects 5.But they are not the only problem, since there also
create_node
calls, where the first parameter is assigned from anTERNARY_TREE
instead of an integer (on occurrence is the expression:term{...} rule).