接續
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
沒有留言:
張貼留言