YACC 응용 예 Desktop Calculator.

Slides:



Advertisements
Similar presentations
Chapter 12. 배열. 배열  동일한 항목들이 동일한 크기로 연속적으로 메모리에 저장되는 구조  동일한 자료 유형이 여러 개 필요한 경우에 이용할 수 있는 자료 구조.
Advertisements

6 장. printf 와 scanf 함수에 대한 고찰 printf 함수 이야기 printf 는 문자열을 출력하는 함수이다. – 예제 printf1.c 참조 printf 는 특수 문자 출력이 가능하다. 특수 문자의 미 \a 경고음 소리 발생 \b 백스페이스 (backspace)
제 3 장 변수와 자료형.
ㅎㅎ 구조체 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스 구조체 배열.
ㅎㅎ 구조체 C++ 프로그래밍 기초 : 객체지향의 시작 구조체 사용하기 함수 매개변수로서의 구조체 구조체 포인터와 레퍼런스
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express.
06 SQL 함수 SQL 함수의 개념 문자 함수 숫자 함수 날짜 함수 데이터 타입의 변환 일반 함수.
제 8 장  파서 생성기 YACC 사용하기.
제 9 장 구조체와 공용체.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
컴퓨터 프로그래밍 기초 [Final] 기말고사
-Part2- 제3장 포인터란 무엇인가.
자료 구조: Chapter 3 (2)구조체, 포인터
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
누구나 즐기는 C언어 콘서트 제4장 수식과 연산자.
제  3 장  Lex 사용하기.
어휘분석기 생성기 Lex.
제 3장. C보다 나은 C++ II.
Lex와 Yacc을 이용한 Calculator 구현
제3장 스택과 큐.
C 프로그래밍.
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
6주차: Functions in C and Others
제 2 장 변수와 상수.
Lex와 Yacc을 이용한 Calculator 구현
2주차: 변수, 수식, Control Flow.
6장. printf와 scanf 함수에 대한 고찰
11장. 1차원 배열.
13. 연산자 오버로딩.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
4. 어휘 분석(Lexical analysis)
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
Report #3 - due: 4/6 100*100의 2개의 희소 행렬 A, B를 전달 받아서 이들의 덧셈을 구하고, 그 결과의 행렬 C를 반환하는 add_sparse_matrix(A, B, C)를 다음과 같이 작성하라. 희소 행렬은 sparse_matrix 타입으로 표현된다.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express Slide 1 (of 22)
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
연산자 (Operator).
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
2장. 변수와 타입.
제 3 강.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
컴퓨터 프로그래밍 기초 - 5th : 조건문(if, else if, else, switch-case) -
8주차: Strings, Arrays and Pointers
5장 선택제어문 if 선택문 switch-case 선택문 다양한 프로그램 작성 조건 연산자.
Chapter 08. 함수.
Choi Seong Yun 컴퓨터 프로그래밍 기초 #03 : 변수와 자료형 Choi Seong Yun
4. 어휘 분석(Lexical analysis)
nauten Compiler – Report Ver.3 Mini-C (주간)
Fucntion 요약.
Canary value 스택 가드(Stack Guard).
^^ Computer Programming 2 dmpr.cnu.ac.kr/~daygax.
데이터 동적 할당 Collection class.
7주차: Functions and Arrays
함수, 모듈.
컴퓨터 프로그래밍 기초 - 11th : 파일 입출력 및 구조체 -
Summary of Pointers and Arrays
Numerical Analysis Programming using NRs
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
어서와 C언어는 처음이지 제21장.
C.
printf("Global Korea\n");
개정판 누구나 즐기는 C언어 콘서트 제13장 동적 메모리 출처: pixabay.
수업 내용 수업 목표 강의 내용 강의 계획서 교과서 및 참고도서 평가 방법 수강생의 학습 방법 제안 강의자료 사이트
Pointers summary.
2019 2학기 9장 배열과 포인터 1. 주소, 주소연산자(&) 2. 포인터, 역참조연산자(*) 3. 배열과 포인터.
Presentation transcript:

YACC 응용 예 Desktop Calculator

Lex Source 수식문법을 위한 lex source %{ #include "y.tab.h" %} %% [0-9]+ return(NUMBER); [ \t] ; \n return(0); \+ return('+'); \* return('*'); . { printf("'%c': illegal character\n", yytext[0]); exit(-1); }

Yacc 입력의 예 수식문법의 예 %token NUMBER %% Exp : Exp '+' Term { printf("rule 1\n"); } | Term { printf("rule 2\n"); } ; Term : Term '*' Num { printf("rule 3\n"); } | Num { printf("rule 4\n"); } Num : NUMBER { printf("rule 5\n"); }

확장 - 1 입력 출력 하나의 식에서 여러 개의 식으로 확장 한 줄에 하나의 식 입력의 끝은 ‘$’ 문자로 표현 빼기(-), 나누기(/), 그리고 괄호 연산 지원 출력 입력된 식의 계산결과를 출력

Lex 입력 %{ #include <stdlib.h> #include "y.tab.h“ extern int yylval; %} %% [0-9]+ {yylval = atoi(yytext); return(NUMBER);} [ \t] ; “$” {return 0; /* end of input */ } \n | . {return(yytext[0]); }

Yacc 입력 %token NUMBER %% ExpList: ExpList Exp {printf(“=%d\n”, $2);} Exp : Exp ‘+’ Term {$$=$1+$3;} | Exp ‘-’ Term {$$=$1-$3;} | Term {$$=$1;} Term : Term '*' Fact {$$=$1*$3;} | Term ‘/’ Fact {$$=$1/$3;} | Fact {$$=$1;} Fact : NUMBER {$$=$1;} | ‘(‘Exp’)’ {$$=$2;}

확장 - 2 입력 출력 변수 지원, 단 변수 이름은 하나의 소문자 입력되는 식에 변수에 대한 배정도 포함 피연산자는 실수도 가능 출력 입력된 식들의 계산결과를 출력 배정문일 경우, 배정되는 값은 출력하지 않는다.

확장 – 2 의 예 입력 a = 10.0 a+1 b = a+10 b+a 출력 11.0 30.0

… 변수를 어떻게 처리? 가능한 변수의 수는 26개임 크기 26인 배열을 사용 인덱스 0 에는 변수 a의 값, 인덱스 1 에는 변수 b의 값, …. 어휘분석 단계에서 변수를 인식하면, 토큰 Name 의 값으로 변수에 대한 인덱스를 전달 double vbltables[26]; a b c d e f g h … 1 2 3 4 5 6 7

토큰의 값 토큰의 값 토큰 값의 타입 여러 타입의 값을 허용하려면 yylval을 통하여 파서에게 전달 yylval의 타입 YYSTYPE 여러 타입의 값을 허용하려면 C: union을 사용 Yacc: %union을 사용

%union 토큰 값의 종류 Yacc에서 토큰의 타입을 정의 각 토큰의 타입을 지정 정수, 실수, 스트링, … 여러 타입의 토큰을 파서에게 전달 Yacc에서 토큰의 타입을 정의 %union { double dval; int vblno; } 각 토큰의 타입을 지정 %token <vblno> NAME %token <dval> NUMBER

문법 기호의 타입 문법 기호의 타입 예 %union에서 정의 %type을 이용하여 지정 %union { double dval; struct symtab *symp; } %token <symp> NAME %token <dval> NUMBER %type <dval> expression

Lex 입력 %{ #include <stdlib.h> #include "y.tab.h“ extern double vbltables[26]; %} %% ([0-9]+ | [0-9]*\.[0-9]+) {yylval.dval = atof(yytext); return(NUMBER);} [ \t] ; [a-z] {yylval.vblno = yytext[0]-’a’; return NAME;} “$” {return 0; /* end of input */ } \n | . {return(yytext[0]); }

Yacc 입력 %{ double vbltables[26]; %} %union { double dval; int vblno; } %token <vblno> NAME %token <dval> NUMBER %type <dval> Fact Term Exp %% StmtList: StmtList Stmt ‘\n’ | Stmt ‘\n’ ; Stmt : NAME ‘=‘ Exp {vbltables[$1] = $3;} | Exp {printf(“=%f\n”, $1);} Exp : Exp ‘+’ Term {$$=$1+$3;} | Exp ‘-’ Term {$$=$1-$3;} | Term {$$=$1;} Term : Term '*' Fact {$$=$1*$3;} | Term ‘/’ Fact {$$=$1/$3;} | Fact {$$=$1;} Fact : NUMBER {$$=$1;} | NAME {$$= vbltables[$1];} | ‘(‘Exp’)’ {$$=$2;}

확장 - 3 변수이름 예 Single character  multiple characters 입력 출력 input = 10.0 result = input+1 result result-input 출력 11.0 1.0

Symbol table 어휘분석 심볼테이블의 구조 변수를 인식하면 심볼테이블을 검색하여, 심볼테이블 항목의 주소를 리턴 //symbol.h #define NSYMS 20 /* maximum number of symbols */ struct symtab { char *name; double value; } symtab[NSYMS]; struct symtab *symlook(); 어휘분석 변수를 인식하면 심볼테이블을 검색하여, 심볼테이블 항목의 주소를 리턴 symlook() 함수를 이용

symlook() 함수 //look up a symbol table entry, add if not present struct symtab *symlook(char *s) { struct symtab *sp; for(sp=symtab; sp < &symtab[NSYMS]; sp++) { /* is it already here ? */ if(sp->name && !strcmp(sp->name, s)) return sp; /* is it free ? */ if(!sp->name) { sp->name=strdup(s); } /* otherwise continue to next */ yyerror(“Too many symbols”); exit(1);

Lex 입력 %{ #include <stdlib.h> #include “symbol.h” #include "y.tab.h“ %} %% ([0-9]+ | [0-9]*\.[0-9]+) {yylval.dval = atof(yytext); return(NUMBER);} [ \t] ; [A-Za-z][A-Za-z0-9]* {yylval.symp = symlook(yytext); return NAME;} “$” {return 0; /* end of input */ } \n | . {return(yytext[0]); }

Yacc 입력 %{ #include “symbol.h” #include <string.h> %} %union { double dval; struct symtab *symp; } %token <symp> NAME %token <dval> NUMBER %type <dval> Fact Term Exp

Yacc 입력 %% StmtList: StmtList Stmt ‘\n’ | Stmt ‘\n’ ; Stmt : NAME ‘=‘ Exp { $1->value = $3;} | Exp {printf(“=%f\n”, $1);} Exp : Exp ‘+’ Term {$$=$1+$3;} | Exp ‘-’ Term {$$=$1-$3;} | Term {$$=$1;} Term : Term '*' Fact {$$=$1*$3;} | Term ‘/’ Fact {$$=$1/$3;} | Fact {$$=$1;} Fact : NUMBER {$$=$1;} | NAME { $$=$1->value;} | ‘(‘Exp’)’ {$$=$2;}

확장 - 4 Allow mathematical functions 예 Such as sqrt(), exp(), log(), … 입력 s2 = sqrt(2) s2 s2*s2 출력 1.41421 2

Naïve approach In Yacc source In Lex source You must hard-code functions into parser and lexer Function names are reserved words %token SQRT LOG EXP … %% Term: … | SQRT ‘(‘ Exp’)’ { $$ = sqrt($3); } | EXP ‘(‘ Exp’)’ { $$ = exp($3); } | LOG ‘(‘ Exp’)’ { $$ = log($3); } … sqrt return SQRT log return LOG exp return EXP

Reserved Words in Symbol Table 심볼 테이블 구조 심볼테이블에 예약어 저장 struct symtab { char *name; double (*funcptr) (); double value; } symtab[NSYMS]; main() { extern double sqrt(), exp(), log(); addfunc(“sqrt”, sqrt); yyparse(); } void addfunc (char *name, double(*func)( ) ) { struct symtab *sp = symlook(name); sp->funcptr = func; }

Reserved Words in Symbol Table In Yacc source In Lex source %token <symp> NAME FUNC … %% Term: … | FUNC ‘(‘ Exp’)’ { $$ = sqrt($3); } [A-Za-z][A-Za-z0-9]* { struct symtab *sp = symlook(yytext); yylval.symp = sp; if(sp->funcptr) /* is it a function? */ return FUNC else return NAME; }