39
6표현식 문장 아꿈사 발표자: 이재정 코드 다운로드: https://github.com/jjuiddong/TCPL

6장 표현식 및 문장

  • Upload
    -

  • View
    574

  • Download
    8

Embed Size (px)

Citation preview

Page 1: 6장 표현식 및 문장

6장 표현식 및 문장아꿈사

발표자: 이재정

코드 다운로드: https://github.com/jjuiddong/TCPL

Page 2: 6장 표현식 및 문장

표현식 : expression문장 : statement컴파일러의 파서에서 흔히 사용하는 문법이다.expression -> unary_expression | assignment_operator

;statement -> if_statement | switch_statement

;

출처:http://www.csci.csusb.edu/dick/samples/c.syntax.html

Page 3: 6장 표현식 및 문장

계산기 프로그램의 구성요소- 입력문 분석기(parser) (=Yacc)- 입력처리 함수 (=Lex)- 기호 테이블- 구동기(driver)

소형 컴파일러에 가깝다.

계산기 프로그램

Page 4: 6장 표현식 및 문장

왜 갑자기 계산기 인가?

아마도?- 컴파일러를 알면 언어를 더 수월하게 이해

할 수 있다.- 컴파일러를 만드는 입장에서 C++을 공부해

보자

- 문법을 잘 이해하는 방법은 역시 문법을 만들어보는 것이다.

Page 5: 6장 표현식 및 문장

계산기 입력 분석기

program: END | expr_list ENDexpr_list: expression PRINT |

expression PRINT expr_list;expression: expression + term |

expression - term |term;

term: term / primary |term * primary |primary;

Page 6: 6장 표현식 및 문장

primary: NUMBER | NAME | NAME = expression |- primary |(expression);

Page 7: 6장 표현식 및 문장

입력 분석기는 재귀적 하강처리(recursive descent)방식으로 해석한다. 흔히 하향식 (top-down)기법이라 한다.

Page 8: 6장 표현식 및 문장

a = 1 + 2program

expr_list

expression PRINT

term

primary

NAME = expression

a expression + term

term primary

primary

NUMBER

NUMBER

1

2

Page 9: 6장 표현식 및 문장

expression 은 primary(기본단위)로 이루어진다.기본단위는 NUMBER, NAME, 사칙연산 *,/,+,- 로 이루어진다.

계산기 입력 분석기(parser)는 기본단위로 이루어진 token들을 의미있는 데이타로 만들어내는 과정을 기술한다.

Page 10: 6장 표현식 및 문장

page 179

double expr(){

double left = term();for(;;)

switch(curr_tok)case PLUS: left += term(); break;case MINUS: left -= term(); break;

return left;}expression: expression + term |

expression - term |term;

Page 11: 6장 표현식 및 문장

page 181

double term(){

double left = prim();for(;;)

switch(curr_tok)case MUL: left *= prim(); break;case DIV: left /= prim(); break;

return left;}term: term / primary |

term * primary |primary;

Page 12: 6장 표현식 및 문장

page 182

double prim(){

switch(curr_tok)case NUMBER:return number_value;case NAME: return table[string_value];case MINUS: return -prim();case '(': return expr();

}primary: NUMBER |

NAME | NAME = expression |- primary |(expression);

Page 13: 6장 표현식 및 문장

입력 처리 함수

page 185

switch-case 문으로 문자 하나하나를 검사해서 token을 얻는다.

Token_value get_token() 함수가 이 역할을 맡는다.

Page 14: 6장 표현식 및 문장

기호 테이블

std::map<string,double> table;

Page 15: 6장 표현식 및 문장

구동기 (driver)int main(){

table["pi"] = 3.1415926535897932385; // insert predefined namestable["e"] = 2.7182818284590452354;

while (cin) {get_token();if (curr_tok == END) break;if (curr_tok == PRINT) continue;cout << expr(false) << '\n';

}

return no_of_errors;}

Page 16: 6장 표현식 및 문장

한정자를 사용한 string 선언std::string str;

전역 네임스페이스를 선언한 후 string 선언using namespace std;string str;

Page 17: 6장 표현식 및 문장

a = 1 + 2;

expr term prim

expr term prim

=

a

1

term prim 2

+

Page 18: 6장 표현식 및 문장

a = 1 x 2 + 3;

expr term prim

expr

=

a

term prim 1

x

prim 2

+

term prim 3

Page 19: 6장 표현식 및 문장

a = 1 + 2 x 3;

expr term prim

expr term

=

a

term prim 2

+

x

prim 3

prim 1

Page 20: 6장 표현식 및 문장

C++ 연산자 요약 정리

생성(메모리 지정) new (expr-list) type(= placement new)

Page 21: 6장 표현식 및 문장

사후 증가 lvalue++사전 증가 ++lvalue~의 주소 &lvalue

Page 22: 6장 표현식 및 문장

L-Value, R-Value

L-Value : 메모리를 가진 데이타, 주소 연산을 통해 주소를 얻어 올 수 있다.

- non-modifiable lvalue- modifiable lvalue

R-Value : 임시 객체나 표현식(expression)

string s1 = "aaa";string s3 = s1 + s2 + string("ccc");function( string("aaa") );string &s4 = "aaa"; // error

Page 23: 6장 표현식 및 문장

C++11 에서는 && 선언으로 R-Value를 레퍼런스로 선언할 수 있다.

Page 24: 6장 표현식 및 문장

연산자 우선 순위a+b*c => a+(b*c)*p++ => (*p)++

우측 결합성(right-associativity)단항 연산자, 대입 연산자a=b=c => a=(b=c)

좌측 결합성, 단항 연산자, 대입 연산자를 제외한 나머지 연산자

a+b+c => (a+b)+c

Page 25: 6장 표현식 및 문장

어휘 토큰으로 인정할 수 있는 가장 긴 문자열이 우선적으로 선택된다.

a+++b = (a++)+b

Page 26: 6장 표현식 및 문장

void f(int x, int y){

int j = x = y;int *p = &++x;int *q = &(x++); // errorint *pp = &(x>y? x:y);

}

Page 27: 6장 표현식 및 문장

int x = f(2) + g(3); // 함수 호출 순서는 미정의int i = 1;v[ i] = i++; // 실행 결과를 예측할 수 없음

단축 평가(short-cut evaluation)&&(and) 연산은 좌변이 true일 때 우변 평가|| (or) 연산은 좌변이 false일 때 우변 평가

Page 28: 6장 표현식 및 문장

& : bit and| : bit or^ : bit xor~ : bit not>> : shift left<< : shift right

비트단위 논리 연산자

Page 29: 6장 표현식 및 문장

증가 연산과 감소 연산

void cpy(char *p, const char *q){

while(*p++ = *q++);}

Page 30: 6장 표현식 및 문장

동적 메모리 할당

new, delete : 힙 메모리에 객체 생성/삭제new[ ], delete[ ] : 힙 메모리에 배열 생성/삭제

Page 31: 6장 표현식 및 문장

메모리 고갈

Page 32: 6장 표현식 및 문장

명시적 타입 변환

static_cast : 같은 클래스 계통 안의 포인터 타입끼리 캐스팅reinterpret_cast : 관련되지 않은 타입 사이 캐스팅

(T)e 캐스팅 ex) int a = (int)b;(T)e 캐스팅은 static_cast, reinterpret_cast, const_cast를 모두 합친 변환함수다.

Page 33: 6장 표현식 및 문장

생성자

T(e) 표기법int i = int(10);string i = string("aa");

템플릿을 작성할 때 기본 타입과 사용자 정의 타입을 구분없이 처리 할 수 있다.

Page 34: 6장 표현식 및 문장

C++ 문장

문장: statementif 문, switch-case문, while 문 등을 뜻한다.

Page 35: 6장 표현식 및 문장

문장으로서의 선언문

코드 중간에 선언문을 놓을 수 있는 것의 장점1. const 를 사용해서 프로그램을 안전성을 높일 수 있다.2. 초기치가 주어질 때까지 객체생성을 미룰 수 있다.

.... program.... string s = "~~~";

Page 36: 6장 표현식 및 문장

조건식 내부에 선언문 두기

if (double d = prim()){~~}

변수의 유효 범위를 가능한 작게 하는 방법

Page 37: 6장 표현식 및 문장

주석문 및 들여쓰기

다음과 같은 주석문은 쓰지말자.// 변수 "v"를 초기화해야 한다.// 변수 "v"는 함수 "f()"에의해서만 초기화되어야 한다.// 이 파일에 있는 다른 함수들보다 "init()"를 먼저 호출할 것// 프로그램의 마지막 부분에서 "cleanup()"을 호출할 것// 함수 "weird" 는 사용하지 말 것// 함수 "f()"는 두 개의 인자를 받는다.

코드에 자연스럽게 녹아 있는 것들은 주석문에 또 등장할 필요가 없다.

Page 38: 6장 표현식 및 문장

저자가 좋아하는 주석문

1. 소스 파일 하나에 대한 주석문.

2. 각 클래스, 템플릿, 네임스페이스에 대한 주석문

3. 주요 함수에 대한 주석문. 여기에는 함수의 용도, 사용된 알고리즘, 함수의 정상 작동을 보장하는 주변 환경에 대한 가정 등이 들어간다.

4. 전역 변수 및 네임스페이스 변수 그리고 상수에 대한 주석문

5. 코드가 단순하지 않은 경우 그리고 이식성이 보장되지 않을 경우에 달아 놓은 주석문

주석문을 잘 쓰는 것도 프로그램 잘 짜는 것만큼 어려우며, 꾸준히 연마해 두면 언젠가는 프로그래밍 능력과 함께 빛날 기술이다.

Page 39: 6장 표현식 및 문장

바른 프로그래밍을 위한 고수의 조언1. 비 표준의 서드 파티 라이브러리 및 직접 손으로 만든 코드 보다는 표준 라이브러리를 우선적으로 고려할 것.2. 복잡한 표현식은 금물3. 연산자 우선순위가 의심되면 괄호를 사용할 것.4. 명시적 타입 변환(캐스트)을 피할 것.5. 명시적 타입 변환을 굳이 사용해야 한다면, C스타일의 캐스트 대신에 C++전용 캐스트 연산자를 사용할 것.6. 결과 값이 잘 정의된 경우에만 T(e) 표기법을 사용할 것.7. 표현식 평가 순서가 불명확해지는 경우를 피하자.8. goto는 가급적 기피 대상.9. do문도 마찬가지10. 어떤 값으로 초기화되기 전엔 그 변수를 선언하지 말자.11. 주석문은 언제나 또박 또박, 명확하게.12. 들여쓰기는 일관성 있게 구사하자.13. 전역 함수 버전의 operator new()를 대신하고 싶으면 멤버 버전의 operator new() 를 우선적으로 고려하자.14. 입력을 처리할 때는 언제든 입력이 엉망으로 들어올 수 있음을 명시할 것.