Presentation is loading. Please wait.

Presentation is loading. Please wait.

Calculator 구현. Simple Calculator 문제 " 입력되는 수식의 값을 계산하는 lex 와 yacc 의 source 을 작성하시오 " – 허용하는 연산자 : + * - / ( ) – 우선순위 : ( ) > * / > + - – 결합순위 : 모두 좌측.

Similar presentations


Presentation on theme: "Calculator 구현. Simple Calculator 문제 " 입력되는 수식의 값을 계산하는 lex 와 yacc 의 source 을 작성하시오 " – 허용하는 연산자 : + * - / ( ) – 우선순위 : ( ) > * / > + - – 결합순위 : 모두 좌측."— Presentation transcript:

1 Calculator 구현

2 Simple Calculator 문제 " 입력되는 수식의 값을 계산하는 lex 와 yacc 의 source 을 작성하시오 " – 허용하는 연산자 : + * - / ( ) – 우선순위 : ( ) > * / > + - – 결합순위 : 모두 좌측 결합 입력 예 (1+2+3)*(2*(51-47)/(1+2*3))

3 실습용 문법 덧셈과 곱셈 식을 생성하는 문법 Exp : Exp ‘+’ Term | Exp ‘-’ Term | Term Term : Term ‘*’ Fact | Term ‘/’ Fact | Fact Fact : ‘(’ Exp ‘)’ | NUMBER

4 Lex 입력 %{ #include "exp.tab.h" %} % [0-9]+{yylval = atoi(yytext);return(NUMBER);} [ \t]; \nreturn(0); \+return('+'); \*return('*');.{ printf("'%c': illegal character\n", yytext[0]); exit(-1); }

5 Yacc 입력 %{ int result; %} %token NUMBER % Exp : Exp '+' Term{ $$ = $1 + $3; result = $$;} | Term{ $$ = $1; } ; Term : Term '*' Num{ $$ = $1 * $3; } | Num{ $$ = $1; } ; Num : NUMBER{ $$ = $1; } ; % main() { yyparse(); printf("Result is %d\n", result); }

6 Calculator 의 확장 -1 To handle variables with single letter names To handle multiple expressions, one per line To use floating point values

7 사용 예 2/3 = 0.666667 a = 2/7 a = 0.285714 z = a + 1 a/z = 0.222222 $

8 Yacc 입력 - 1 %{ double vbltable[26]; %} %union { double dval; int vblno; } %token NAME %token NUMBER %left '-' '+' %left '*' '/' %nonassoc UMINUS %type expression %

9 Yacc 입력 - 2 statement_list: statement '\n' | statement_list statement '\n‘ ; statement: NAME '=' expression { vbltable[$1] = $3; } | expression { printf("= %g\n", $1); } ; expression: expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { if ( $3 == 0.0 ) yyerror("divide by zero"); else $$ = $1 / $3; } | '-' expression %prec UMINUS { $$ = -$2; } | '(' expression ')' { $$ = $2; } | NUMBER { $$ = $1; } | NAME { $$ = vbltable[$1]; } ;

10 Calculator 의 확장 -2 To allow longer variable names –Symbol table is needed to keep tracks of the name in use #define NSYMS 20 struct symtab { char *name; double value; } symtab[NSYMS]; struct symtab *symlook();

11 symlook() struct symtab *symlook(char *s) { char *p; struct symtab *sp; for(sp = symtab; sp < &symtab[NSYMS]; sp++) { if(sp->name && !strcmp(sp->name, s)) return sp; if(!sp->name) { sp->name = strdup(s); return sp; } yyerror("Too many symbols"); exit(1); }

12 Lex & Yacc 입력 Lex 입력 : 4.l Yacc 입력 : 4.y 심볼테이블 헤더 : 4hdr.h

13 Calculator 의 확장 -3 To allow mathematical functions –Square root, exponential, logarithm s2 = sqrt(2) s2 = 1.41421 s2*s2 =2

14 First approach %token SQRT LOG EXP... %... expression:... | SQRT '(' expression ')' { $$ = sqrt($3);} | LOG '(' expression ')' { $$ = log($3);} | EXP '(' expression ')' { $$ = exp($3);} In lex.... sqrt return SQRT; log return LOG; exp return EXP;...

15 Another approach Reserved words in the symbol table #define NSYMS 20 struct symtab { char *name; double (*funcptr)(); double value; } symtab[NSYMS]; struct symtab *symlook();

16 main() { extern double sqrt(), exp(), log(); addfunc("sqrt", sqrt); addfunc("exp", exp); addfunc("log", log); yyparse(); } addfunc(char *name, double (*func)()) { struct symtab *sp = symlook(name); sp->funcptr = func; }

17 Lex & Yacc 입력 Lex 입력 : 5.l Yacc 입력 : 5.y 심볼테이블 헤더 : 5hdr.h


Download ppt "Calculator 구현. Simple Calculator 문제 " 입력되는 수식의 값을 계산하는 lex 와 yacc 의 source 을 작성하시오 " – 허용하는 연산자 : + * - / ( ) – 우선순위 : ( ) > * / > + - – 결합순위 : 모두 좌측."

Similar presentations


Ads by Google