1 / 17

Calculator 구현

Calculator 구현. Simple Calculator. 문제 " 입력되는 수식의 값을 계산하는 lex 와 yacc 의 source 을 작성하시오 " 허용하는 연산자 : + * - / ( ) 우선순위 : ( ) > * / > + - 결합순위 : 모두 좌측 결합 입력 예 (1+2+3)*(2*(51-47)/(1+2*3)). 실습용 문법. 덧셈과 곱셈 식을 생성하는 문법 Exp : Exp ‘+’ Term | Exp ‘-’ Term | Term

thetis
Download Presentation

Calculator 구현

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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] ; \n return(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 <vblno> NAME %token <dval> NUMBER %left '-' '+' %left '*' '/' %nonassoc UMINUS %type <dval> 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

More Related