1

C コンパイラを構築するために、次の .y コードを実行したいと考えています。コードはこの本から正確に取られました

次の 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

この問題を解決するために私にアドバイスをくれるメンターはいますか?ありがとうございます

4

2 に答える 2

4

$$エラーは、違法である midaction ルールでの (タイプ タグが含まれていない) の使用について不平を言っています。$$in midaction ルールのすべての使用には、type タグが必要です。興味深いことに、すべての使い方が間違っているわけではありません$<labels>$

$$あなたがする必要があるのは、すべてのミッドルールアクションで置き換えることだと思います$<labels>$(ただし、ルールの終わりのアクションではありません...)最も簡単なのは、エラーメッセージを確認することです(各行と列を見てください) )、それ$$を置き換えます$<labels>$

于 2013-10-28T22:50:21.373 に答える