2010年9月7日 星期二

LEX && YACC sample case pt2

接續 LEX && YACC sample case pt1 幫 List-Node 穿上 Lex && Yacc 的衣服....^_^.再依序填入List中. sample.l
%{
#include "y.tab.h"
%}

%%
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
  yylval.dval = atof(yytext);
  return NUMBER;
 }

[ \t] ;   /* ignore white space */

[A-Za-z][A-Za-z0-9]* { /* return symbol pointer */
  return NAME;
 }

"$" { return 0; }

\n |
. return yytext[0];
%%
int yywrap()
{
    return 1;
}
sample.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "tt.h"
int OpId =0;
struct LIST   *lstr; 
%}

%union {
 double dval;
}
%token <dval> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%type <dval> expression
%%
statement_list: statement '\n'
 | statement_list statement '\n'
 ;

statement: NAME '=' expression { $1 = $3; }
 | expression  { printf("= %g\n", $1);
  displayOp();
  OpId =0; 
  lstr =NULL;
 }
 ;

expression: expression '+' expression { $$ = $1 + $3; 
    LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_ADD,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '-' expression { $$ = $1 - $3; 
    LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_SUB,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '*' expression { $$ = $1 * $3;
     LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_MUL,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
  }
 | expression '/' expression
    { if($3 == 0.0)
      yyerror("divide by zero");
     else{
      $$ = $1 / $3;
     LIST *tlstr = (void *)lstr; //LIST list
    tlstr = set_List(tlstr,OpId,TT_DIV,$1,$3,$$); OpId++;
    lstr = (void *)tlstr;   
     }
    }
 | '-' expression %prec UMINUS { $$ = -$2; }
 | '(' expression ')' { $$ = $2; }
 | NUMBER
 | NAME   { $$ = $1; }
 ;
%%

int displayOp(){
LIST *tlstr = (void *)lstr;
TT   *tPtr = NULL; //TT   point
LIST *lPtr = NULL; //LIST point

int i=0;
char* Opst;
for(i=0; i<OpId; i++){

 if(tlstr == NULL ){ printf("<E1> Initial List Error ...\n"); return -1; }
 lPtr = get_List(tlstr,i);

 switch(lPtr->Typ){
   case TT_ADD : printf("Op(%d) -> ADD\n",i);  break;
   case TT_SUB : printf("Op(%d) -> SUB\n",i);  break;
   case TT_MUL : printf("Op(%d) -> MUL\n",i);  break;
   case TT_DIV : printf("Op(%d) -> DIV\n",i);  break;
   case TT_MOD : printf("Op(%d) -> MOD\n",i);  break;
 default: return -1; break;
        }

 printf("SRC1...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Parent;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Parent Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_SRC1);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Parent->Src1 Error ...\n"); return -1; }
 display_TTNode(tPtr);

 printf("SRC2...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Parent;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Parent Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_SRC2);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Parent->Src2 Error ...\n"); return -1; }
 display_TTNode(tPtr);

 printf("DST...\n");
 if(lPtr == NULL ){ printf("<E2> Get Ptr Error ...\n"); return -1; }
 tPtr = (void *)lPtr->Child;
 if(tPtr == NULL ){ printf("<E3> Get Ptr->Child Error ...\n"); return -1; }
 tPtr = get_TTNode(tPtr,TT_DST);
 if(tPtr == NULL ){ printf("<E4> Get Ptr->Child->DST Error ...\n"); return -1; }
 display_TTNode(tPtr);
 }

 printf("=====================\n");
 printf("\n");
 printf("\n");
}


int yyerror(char const *str)
{
    extern char *yytext;
    fprintf(stderr, "parser error near %s\n", yytext);
    return 0;
}

int main(void)
{
    extern int yyparse(void);
    extern FILE *yyin;

    yyin = stdin;
    if (yyparse()) {
        fprintf(stderr, "Error ! Error ! Error !\n");
        exit(1);
    }
}

Results: (1+2)*2 = 6 Op(0) -> ADD SRC1... Id :: 5,Nm :: 1.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 3.000000 Op(1) -> MUL SRC1... Id :: 5,Nm :: 3.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 6.000000 ===================== 1+2*2 = 5 Op(0) -> MUL SRC1... Id :: 5,Nm :: 2.000000 SRC2... Id :: 6,Nm :: 2.000000 DST... Id :: 7,Nm :: 4.000000 Op(1) -> ADD SRC1... Id :: 5,Nm :: 1.000000 SRC2... Id :: 6,Nm :: 4.000000 DST... Id :: 7,Nm :: 5.000000 ===================== project download here Refs lex&yacc 第一章例5 lex & yacc, 2nd Edition lex_and_yacc_chinese_version

沒有留言:

張貼留言