1

我想運行下面的.y代碼來構建一個C編譯器。該代碼是從this Bookyacc錯誤:''x'沒有聲明類型

exactky採取以下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

回答

0

您使用的是哪個版本的bison/yacc?什麼是命令行?我的版本給這些(很常見)的消息:

[Charlies-MacBook-Pro:~/junk] crb% bison x.y 
x.y: conflicts: 6 shift/reduce 
[Charlies-MacBook-Pro:~/junk] crb% bison --version 
bison (GNU Bison) 2.3 
Written by Robert Corbett and Richard Stallman. 

它似乎說你的語法大多是好的。

也許張貼你的Makefile,看看你的野牛版本。

+0

thnx,CHarlie您的觀察。但我故意忽略那些規則,因爲錯誤沒有顯示在這些部分 – sabu

+0

最好發佈一個可編譯的(在這個case yaccable)的例子,而不僅僅是它的一部分。 –

+0

我編輯我的文章,並給出完整的代碼。 – sabu

3

錯誤是抱怨在作爲規則中使用了$$(沒有包含類型標籤),這是非法的。在midaction規則中,所有使用$$都需要一個類型標記。有趣的是,並非所有的使用都是不正確的 - 其中有些使用類型標籤$<labels>$

我認爲你需要做的是在所有中間規則操作中(而不是在規則結束操作中)替換$$$<labels>$最簡單的方法是查看錯誤消息(查看每一行的行和列),並用替換$<labels>$