我想运行以下 .y 代码来构建 C 编译器。代码取自这本书
下面的 miniC.y 代码是:
%{
#include <stdio.h>
#include "mini.h"
#include "miniC.h"
%}
%union {
ADDRESS address;
int code; /* comparison code 1-6 */
struct {int L1;
int L2;
int L3;
int L4;} labels;
}
%token <address> IDENTIFIER
%token <code> INT
%token <code> FLOAT
%token FOR
%token WHILE
%token <code> COMPARISON
%token IF
%token ELSE
%token <address> NUM
%type <code> Type
%type <address> Expr
%type <address> OptExpr
%type <labels> WhileStmt
%type <labels> ForStmt
%type <labels> IfStmt
%type <labels> Label
%right '='
%left COMPARISON
%left '+' '-'
%left '*' '/'
%left UMINUS UPLUS
%%
Function: Type IDENTIFIER '(' ArgListOpt ')' CompoundStmt
;
ArgListOpt: ArgList
|
;
ArgList: ArgList ',' Arg
| Arg
;
Arg: Type IDENTIFIER
;
Declaration: Type {dcl = TRUE;
identType = $1;}
IdentList ';' {dcl = FALSE;}
;
IdentList: IDENTIFIER ',' IdentList
| IDENTIFIER
;
Type: INT {$$ = $1;}
| FLOAT {$$ = $1;}
;
Stmt: ForStmt
| WhileStmt
| Expr ';'
| IfStmt
| CompoundStmt
| Declaration
| ';' /* null statement */
;
ForStmt: FOR '(' Expr ';' {$$.L1 = newlabel();
atom (LBL,NULL,NULL,NULL,0,$$.L1);}
OptExpr ';' {$$.L2 = newlabel();
atom (TST,$6,zero,NULL,6,
$<labels>$.L2);
$$.L3 = newlabel();
atom (JMP,NULL,NULL,NULL,0,
$<labels>$.L3);
$$.L4 = newlabel();
atom (LBL,NULL,NULL,NULL,0,
$<labels>$.L4);}
OptExpr ')' {atom (JMP,NULL,NULL,NULL,0,
$<labels>5.L1);
atom (LBL,NULL,NULL,NULL,0,
$<labels>8.L2);}
Stmt {atom (JMP,NULL,NULL,NULL,0,
$<labels>8.L4);
atom (LBL,NULL,NULL,NULL,0,
$<labels>8.L3);}
;
OptExpr: Expr {$$ = $1;}
| {$$ = one;} /* default to inf loop */
;
WhileStmt: WHILE {$$.L1 = newlabel();
atom (LBL,NULL,NULL,NULL,0,$$.L1);}
'(' Expr ')' {$$.L2 = newlabel();
atom (TST,$4, zero, NULL,1,$$.L2);}
Stmt {atom (JMP,NULL,NULL,NULL,0,
$<labels>2.L1);
atom (LBL,NULL,NULL,NULL,0,
$<labels>6.L2);}
;
IfStmt: IF '(' Expr ')' {$$.L1 = newlabel();
atom (TST, $3, zero, NULL, 1, $$.L1);}
Stmt {$$.L2 = newlabel();
atom (JMP,NULL,NULL,NULL,0, $$.L2);
atom (LBL,NULL,NULL,NULL,0,
$<labels>5.L1);}
ElsePart {atom (LBL,NULL,NULL,NULL,0,
$<labels>7.L2);}
;
ElsePart:
| ELSE Stmt
;
CompoundStmt: '{' StmtList '}'
;
StmtList: StmtList Stmt
|
;
Expr: IDENTIFIER '=' Expr {atom (MOV, $3, NULL, $1,0,0);
$$ = $3;}
| Expr COMPARISON Expr
Label {$$ = alloc(1);
atom (MOV, one, NULL, $$,0,0);
atom (TST, $1, $3, NULL, $2, $4.L1);
atom (MOV, zero, NULL, $$,0,0);
atom (LBL,NULL,NULL,NULL,0,$4.L1);}
| '+' Expr %prec UPLUS {$$ = $2;}
| '-' Expr %prec UMINUS {$$ = alloc(1);
atom (NEG, $2,NULL,$$,0,0); }
| Expr '+' Expr {$$ = alloc(1);
atom (ADD, $1, $3,$$,0,0); }
| Expr '-' Expr {$$ = alloc(1);
atom (SUB, $1, $3, $$,0,0); }
| Expr '*' Expr {$$ = alloc(1);
atom (MUL, $1, $3, $$,0,0); }
| Expr '/' Expr {$$ = alloc(1);
atom (DIV, $1, $3, $$,0,0); }
| '(' Expr ')' {$$ = $2;}
| IDENTIFIER {$$ = $1; }
| NUM {$$ = $1; }
;
Label: {$$.L1 = newlabel();}
; /* Used to store a label in
compare expr above */
%%
char *progname;
char * op_text();
int lineno = 1;
ADDRESS save;
ADDRESS one;
ADDRESS zero;
int nextlabel = 1;
#include "lex.yy.c"
#include "gen.c"
main (int argc, char *argv[]){
progname = argv[0];
atom_file_ptr = fopen ("atoms", "wb");
strcpy (yytext,"0.0");
zero = searchNums(); /* install the constant 0.0 in table */
strcpy (yytext, "1.0");
one = searchNums(); /* also 1.0 */
yyparse();
fclose (atom_file_ptr);
if (!err_flag) code_gen();
}
yyerror (char * s){
fprintf(stderr, "%s[%d]: %s\n", progname, lineno, s);
printf ("yytext is <%s>", yytext);
err_flag = TRUE;
}
newlabel (void){ return nextlabel++;}
atom (int operation, ADDRESS operand1, ADDRESS operand2,
ADDRESS result, int comparison, int dest)
/* put out an atom. destination will be a label number. */
{ struct atom outp;
outp.op = operation;
outp.left = operand1;
outp.right = operand2;
outp.result = result;
outp.cmp = comparison;
outp.dest = dest;
fwrite (&outp, sizeof (struct atom), 1, atom_file_ptr);
}
decode (int atom){
switch (atom){
case ADD: strcpy (mne, "ADD");
break;
case SUB: strcpy (mne, "SUB");
break;
case MUL: strcpy (mne, "MUL");
break;
case DIV: strcpy (mne, "DIV");
break;
case JMP: strcpy (mne, "JMP");
break;
case NEG: strcpy (mne, "NEG");
break;
case LBL: strcpy (mne, "LBL");
break;
case TST: strcpy (mne, "TST");
break;
case MOV: strcpy (mne, "MOV");
}
}
错误是:
miniC.y:65.42-43: $$ for the midrule at $5 of 'ForStmt' has no declared type
miniC.y:66.69-70: $$ for the midrule at $5 of 'ForStmt' has no declared type
miniC.y:67.42-43: $$ for the midrule at $8 of 'ForStmt' has no declared type
miniC.y:70.42-43: $$ for the midrule at $8 of 'ForStmt' has no declared type
miniC.y:73.42-43: $$ for the midrule at $8 of 'ForStmt' has no declared type
miniC.y:88.42-43: $$ for the midrule at $2 of 'WhileStmt' has no declared type
miniC.y:89.69-70: $$ for the midrule at $2 of 'WhileStmt' has no declared type
miniC.y:90.42-43: $$ for the midrule at $6 of 'WhileStmt' has no declared type
miniC.y:91.69-70: $$ for the midrule at $6 of 'WhileStmt' has no declared type
miniC.y:97.42-43: $$ for the midrule at $5 of 'IfStmt' has no declared type
miniC.y:98.72-73: $$ for the midrule at $5 of 'IfStmt' has no declared type
miniC.y:99.42-43: $$ for the midrule at $7 of 'IfStmt' has no declared type
miniC.y:100.70-71: $$ for the midrule at $7 of 'IfStmt' has no declared type
make: *** [y.tab.c] Error 1
我的makefile包含:
miniC: lex.yy.c y.tab.c
gcc -g y.tab.c -o miniC -ly -ll
lex.yy.c:miniC.l
lex miniC.l
y.tab.c:miniC.y
yacc -d miniC.y
任何导师都可以出面建议我解决这个问题。感谢 Yoy