Home [컴퓨터과학 개론] 11강 - 프로그래밍 언어
Post
Cancel

[컴퓨터과학 개론] 11강 - 프로그래밍 언어

💡해당 게시글은 방송통신대학교 이관용, 정광식 교수님의 '컴퓨터과학 개론' 강의를 개인 공부 목적으로 메모하였습니다.



학습 개요


  • 프로그래밍 언어의 개념과 분류, 실행을 위한 코드 변환, 그리고 프로그래밍 언어의 구문과 구조, 부프로그램과 매개 변수 등에 대해서 이해함



학습 목표


  • 프로그래밍 언어의 필요성과 발전 과정을 이해할 수 있음
  • 프로그래밍 언어의 문법, 컴파일 과정의 개념을 이해할 수 있음



강의록


프로그래밍 언어의 개요

프로그래밍 언어의 개요

  • 개념
    • 프로그래밍 언어는 사람의 의도를 컴퓨터에게 전달하여 컴퓨터에게 작업을 수행 시키기 위해 만들어짐
    • 프로그래밍 언어는 사람의 의도를 추상화하여 압축된 언어컴퓨터에 전달되어야 함
    • 동시에 컴퓨터에서 실행될 수 있는 이진 코드(binary code)로 번역되어야 함
    • 만약 일상 언어로 프로그램을 작성할 수 있다면 누구나 자신의 필요에 따라 프로그램을 작성할 수 있음
    • 하지만, 일상 언어로 작성된 프로그램은 애매모호한 의미를 가질 수 있으며, 하나의 문장에서 두 개의 의미로 해석이 될 수도 있음
    • 프로그래밍 언어는 의미적으로 애매모호함이 없고 어떤 경우에도 동일한 의미로 해석되어야 함
    • 구문론적 측면에서 명확하게 정의되어야 하며, 의미론적 측면에서 언제나 동일하게 해석되어야 함
    • 프로그래밍 언어는 논리적으로 설계되어 컴퓨터가 처리할 수 있는 이진 코드로의 변환이 명확하고 정확하게 되어야 함

프로그래밍 언어의 전형

  • 종류
    • 프로그래밍 언어는 이진 코드에 가까운 어셈블리어와 자연어에 가까운 고급 언어로 분류됨
    • 어셈블리어와 고급 언어 사이에 다양한 프로그래밍 언어가 존재함
  • 기계어
    • 0과 1의 이진수로 구성되는 언어로 컴퓨터 하드웨어를 직접적으로 제어하기 위한 전기 신호의 표현 형태로 전달될 수 있는 수준의 언어
    • 0과 1로 이루어져 있기 때문에 사람이 의미를 이해하기 어렵고, 프로그램 작성이 매우 어려움
    • 하드웨어나 컴퓨터 구조에 따라 기계어의 구성과 명령어(0과 1의 나열)가 달라지기 때문에 범용성이 떨어짐
  • 어셈블리어
    • 기계어의 0과 1로 이루어진 명령어를 사람의 언어와 유사한 알파벳 심벌 형태로 바꾼 언어임
    • 기계어보다는 훨씬 읽기 편하지만 프로그램의 실행 논리를 컴퓨터가 실행하는 논리 순서에 맞추어 생각해야 하기 때문에 이해하기 쉽지 않음
  • 초창기의 고급 프로그래밍 언어

    1
    2
    3
    
      FOR A = 1 TO 10
      PRINT StudentName; " ";
      NEXT A
    
    • 연산, 수행 제어, 메모리 접근 등의 프로그램을 사람의 자연어에 유사한 형태로 표현
    • 포트란(FORTRAN, 과학/공학 계산용 언어, 최초의 고급 언어)이나 코볼(COBOL, 비지니스용 언어) 등이 초기의 고급 프로그래밍 언어에 해당됨(1950년대 말)
    • 1960년대 중반에 등장한 베이직(Basic)도 1980년대 마이크로컴퓨터에서 많이 사용됨
  • 함수형 프로그래밍 언어

    1
    2
    3
    
      (+ 3 2);
      (length (a b c));
      (+ 1 (if t 2 3)) ;
    
    • 기본적으로 수식(expression)의 연속으로 이루어져 있고 함수들을 사용해 수식을 변환
    • 수식은 사칙 연산 뿐만 아니라 일반적인 의미의 모든 함수를 의미하고, 함수의 결과를 다른 함수의 입력 값으로 사용함
    • 리스프(LISP, 1950년대 말)와 같이 심벌의 리스트를 연산의 기본 단위로 하기도 함
    • 스킴(Scheme), ML 등의 고급 언어도 함수형 언어에 포함됨
  • 구조적 프로그래밍 언어
    • 우리가 현대의 프로그래밍 언어에서 사용하는 많은 개념들이 구조적 프로그래밍 언어에서 도입됨
    • 1950년대 말에 나온 알골 60(Algol 60)은 조건문과 반복문을 사용하여 실행 흐름을 제어하고, 블록(block) 구조, 함수 호출 등 주요 개념을 도입함
    • 이후의 구조적인 프로그래밍 언어인 파스칼(Pascal), C, 모듈라-2(Modula-2) 등에 영향을 줌

      1
      2
      3
      4
      5
      6
      
        if (a >= b) {
            d = a - b;
            printf("%d", b);
        }
        else
            printf("%d", a);
      
  • 논리형 프로그래밍 언어

    1
    2
    3
    
      father(a, b)
      father(b, c)
      grandfather(X, Z) :- father(X, Y), father(Y, Z)
    
    • 형식 논리로 사실(fact)들과 규칙(rule)들로 이루어진 문제 도메인 모델을 정의함
    • 원하는 결과를 얻기 위해 문제 도메인에 대한 질의를 주어서 논리적인 추론에 기초한 결과가 나오게 하는 선언형 언어임
    • 1970년대에 등장하여 1980년대에 인공 지능 분야의 인기와 더불어 많은 주목을 받은 프롤로그(Prolog)가 대표적인 예라고 할 수 있음
  • 객체 지향 프로그래밍 언어
    • 객체(object) 개념을 정의하고, 객체에 대한 연산(메소드)과 성질(멤버 변수)을 정의하여 프로그램을 작성하는 언어임
    • 구조적인 프로그래밍 언어와 달리 객체 중심의 사고의 틀을 제공함
    1
    2
    3
    4
    5
    
      public class HelloWorldApp {
          public static void main(String[] args) {
              System.out.println("Hello World!");
          }
      }
    
    • 최초로 클래스 개념을 갖춘 Simula 67은 1960년대 말에 등장했지만 C++, 스몰톡-80(Smalltalk 80)등은 1980년대에 등장
    • 1990년대 중반에 등장한 자바(Java)도 현재 가장 대표적인 객체 지향 프로그래밍 언어임
  • 스크립트 언어
    • 유닉스(Unix)와 같은 운영 체제의 관리와 자동화를 위해 만들어져 사용되기 시작한 언어임
    • 쉘 스크립트(sh, bash, csh 등)와 패턴 처리 스크립트 언어(awk, sed) 등에서 시작됨
    • 펄(Perl), 파이선(Python) 등 스크립트 언어들이 웹 기반 서비스에서 많이 사용되고 있음

정리 문제

  • 다음과 같은 프로그램이 속하는 언어 부류는 무엇인가?

    1
    2
    3
    
      (+ 3 2);
      (length (a b c));
      (+ 1 (if t 2 3));
    
    • 함수형 언어

프로그래밍 언어의 파스 트리

프로그래밍 언어의 파스 트리

  • 개요
    • 모든 언어는 사용 될 수 있는 단어들의 집합단어들이 나열되어 만들어지는 구조에 대한 규칙(문법)에 따라 문장을 생성하고 각각의 문장은 실제 세계와 연결되는 의미를 가짐

      image.png

    • 대부분의 프로그래밍 언어는 형식 문법을 사용해서 언어의 구조를 기술함

      • 문장의 구조는 파스 트리(parse tree)의 형태로 표현하면 이해가 빠르고 문법의 모호성을 파악하기 쉬움

형식 문법의 요소

  • 단말 심벌
    • 문장을 이루는 단어들을 단말 심벌이라 함
      • 파스 트리의 단말 노드에 해당됨
    • 자연어에서는 사전에 나오는 모든 단어가 단말 심벌이 됨
  • 비 단말 심벌
    • 비 단말 심벌은 단말 심벌이 아니면서 복합적으로 나열된 단말 심벌과 비 단말 심벌의 조합으로 구성됨
    • 파스 트리의 내부 노드에 해당됨
    • 자연어에서는 <명사구>, <동사구>, <문장> 등이 비 단말 심벌임
  • 생성 규칙
    • 하나의 비 단말 심벌이 다른 단말 심벌이나 비 단말 심벌로 대체되는 규칙
    • 예를 들어 영어라면
      • <문장> → <명사구> <동사구>
      • <명사구> → <관사> <명사>
      • <명사> → "dog" | "cat" | "rat"
      • <동사> → "bark" | "chase" | "eat" 등이 생성 규칙임
  • 시작 심벌
    • 가장 상위 계층의 비 단말 심벌로 보통 **<문장>이 시작 심벌**임
    • 파스 트리의 루트 노드에 해당됨

문장의 구조와 간단한 문법을 사용한 구문 분석

  • “The cat ate the rat” 문장의 파스 트리 분석

    image.png

    • <문장> → <명사구> <동사구>
    • <동사구> → <동사> <명사구> | <동사>
    • <명사구> → <관사> <명사> | <명사>
    • <관사> → "a" | "the"
    • <동사> → "eat" | "ate" | "see" | "sees" | "saw"
    • <명사> → "cat" | "rat" | "dog"

프로그래밍 언어의 분석

프로그래밍에서 실행 가능 코드

  • 실행 가능 코드
    • 프로그래밍 언어로 작성된 프로그램 코드는 사람이 읽고 이해하기가 쉽지만, 그 자체로는 컴퓨터가 이해할 수 없으며 실행할 수가 없음
    • 사람이 작성한 프로그램을 분석하여 기계어의 이진 코드로 바꾸는 변환 과정을 거치면 컴퓨터가 이해하고 실행할 수 있는 프로그램이 됨

프로그램 코드의 분석

  • 프로그램 코드의 분석
    • 사람이 작성한 프로그램은 어휘 분석과 구문 분석을 통해 프로그램에 문제가 없음을 확인
    • 어휘 분석과 구문 분석 과정을 통과한 후 최종적으로 코드 생성 단계에서 실제 실행 가능한 이진 기계어 코드가 생성됨
      • 어휘 분석 → 구문 분석 → 코드 생성
  • 어휘 분석
    • 프로그램을 구성하는 문자들의 나열로부터 단어(토큰)를 추출해 내는 과정임
    • 빈 칸을 기준으로 단어를 구분하고, 구분된 각 단어를 이름, 숫자, 수식 기호 등으로 분류하는 것이 어휘 분석임
    • 어휘 분석의 결과로 나온 개개의 단어를 토큰(token)이라고 함
  • 구문 분석
    • 어휘 분석의 결과로 나온 토큰들의 나열이 해당 프로그래밍 언어의 문법에 맞는 지를 확인하는 과정
    • 언어 문법의 적합성 확인을 위한 파스 트리의 생성
  • 실행 코드의 생성
    • 프로그래밍 언어에 대한 구문 분석의 결과로 변수, 상수, 제어의 흐름 등이 결정되면, 이러한 각각의 명령어를 어셈블리어로 풀어 쓰거나 직접 기계어 이진 코드가 생성

정리 문제

  • 고급 언어 프로그램에서 실행 코드까지의 변환 순서로 올바른 것은?
    • 어휘 분석, 구문 분석, 코드 생성

프로그래밍 언어의 공통 개념

대입문

  • 개요
    • 대입문(할당문)은 변수나 기억 장치 주소에 값을 저장하는 역할을 함
    • 대입문은 명령형 언어의 가장 중요한 기능 중의 하나임
    • 대입문은 보통 다음과 같은 일반적인 형태를 가짐

      1
      
        <수식1> = <수식2>
      
      • <수식1>
        • 왼쪽 값(l-value)
        • 값이 저장될 위치(기억 장치의 주소)를 가리킴
      • <수식2>
        • 오른쪽 값(r-value)
        • **<수식1>이 가리키고 있는 곳(기억 장치의 주소)에 저장될 값**(정수 값, 실수 값, 문자열 등)을 의미함
    • 대입문은 <수식 2>의 값<수식 1>‘주소가 가리키는 기억 장치의 저장소’에 ‘저장’ 함

      1
      
        x = x + 1
      

      image.png

변수형 검사

  • 개요
    • 변수형은 연산에 사용되는 상수(constant)나 변수(variable)의 종류를 지정해서 연산 수행 시에 호환성이 없는 변수형 간의 연산을 막아서 연산의 결과로 얻게 되는 정보의 손실을 최소화하기 위해 사용
      • ex) 정수를 문자열로 나누거나 복잡한 구조체(struct) 타입으로 곱하는 것은 연산의 의미가 없음

      image.png

    • 정수와 실수의 덧셈에서 정수형으로 연산을 수행하면 실수 값의 일부분을 잃게 됨
      • ex) 3 + 2.5 = ?
    • 변수형이 호환되지 않는 연산을 찾아내는 것을 형 검사라고 함
    • 형 검사는 컴파일 과정에서 이루어지는 정적(static) 형 검사 방식과 프로그램의 실행(run-time) 중에 이루어지는 동적(dynamic) 형 검사 방식이 있음
    • 프로그래밍 언어에 따라 변수형을 다루는 방법과 변수형을 제한하는 정도에도 많은 차이가 있음
    • ex) 숫자 10과 문자열 ‘33’을 더하는 것을 허용하는 프로그래밍 언어도 있고 허용하지 않는 프로그래밍 언어(Perl)도 있음

      1
      2
      3
      4
      
        x = 10 + '33';
        print x;
              
        # 출력값: 43
      
  • C 언어

    1
    2
    
      int x = 10 + "30";
      printf("%d",x);
    
    • 결과는 컴파일러에 따라 다를 수 있음
    • gcc 컴파일러의 경우 출력 값
      • 134513854
    • 컴파일 시 경고가 발생함
      • warning: initialization makes integer from pointer without a cast
    • C와 같이, 모든 변수형을 변수의 선언에서 지정해주고 모든 연산에서 변수형을 검사하는 언어에서도 특정 경우에 다른 변수형 간의 연산이 필요할 때가 있음
    • 올바른 연산을 위해 한 변수나 데이터의 형을 수동으로 전환 시켜주는 것이 형 변환(type casting)
      • 컴파일러 경고 중에 “cast”란 단어가 바로 이 캐스팅을 의미함

정리 하기

  • 프로그래밍 언어의 파스 트리
    • 단말 심벌
      • 문장을 이루는 단어들
    • 비 단말 심벌
      • 단말 심벌이 아니라 복합적으로 나열된 단말 심벌과 비 단말 심벌의 조합
  • 프로그램에서 실행 가능 코드로의 변환
    • 어휘 분석
      • 프로그램을 구성하는 문자들의 열로부터 단어들을 추출해내는 과정
    • 구문 분석
      • 어휘 분석의 결과로 나온 토큰들의 나열이 해당 프로그래밍 언어의 문법에 맞는 지를 확인하는 과정
    • 코드 생성
      • 구문 분석의 결과로 변수, 상수, 제어의 흐름 등이 결정되면 이러한 각 명령어를 어셈블리어로 쓰거나 직접 기계어의 이진 코드 생성
  • 프로그래밍 언어의 기본 공통 개념
    • 대입문(할당)
      • 변수나 기억 장치 주소에 값을 저장하는 역할



연습 문제


  1. 다음 중 스크립트 언어에 해당되는 것은?

    a. 펄(Perl)

    • 스크립트 언어는 유닉스(unix)와 같은 운영체제의 관리와 자동화를 위해 만들어져 사용되기 시작한 언어이며, 쉘 스크립트(sh, bash, csh 등)와 패턴 처리 스크립트 언어(awk, sed) 등에서 시작되었음
    • 최근에는 펄(Perl), 파이썬(Python) 등 스크립트 언어들이 웹 기반 서비스에서 많이 사용되고 있음
  2. 형식 문법의 파스 트리에서 중간 노드에 해당하는 것은?

    a. 비 단말 터미널

    • 단말 심벌(terminal symbol)
      • 문장을 이루는 단어들
      • 파스 트리의 단말 노드에 해당 됨
      • 자연어에서는 사전에 나오는 모든 단어가 단말 심벌이 됨
    • 비 단말 심벌(non-terminal symbol)
      • 단말 심벌이 아니면서 복합적으로 나열된 단말 심벌과 비 단말 심벌의 조합으로 구성 됨
      • 즉, 파스 트리의 내부 노드에 해당 됨
      • 자연어에서는 <명사구>, <동사구>, <문장> 등이 비 단말 심벌임
    • 생성 규칙(production rule)
      • 하나의 비 단말 심벌이 어떻게 다른 단말 심벌이나 비 단말 심벌을 대체할 수 있는지 정의하는 규칙을 말함
      • 영어일 경우
        • <문장> → <명사구> + <동사구>
        • <명사구> → <관사> + <명사>
        • <명사> → “dog”|”cat”|”rat”
        • <동사> → “bark”|”chase”|”eat” 등이 생성 규칙임
    • 시작 심벌(start symbol)
      • 가장 상위 계층의 비 단말 심벌로 보통 <문장>이 시작 심벌임
      • 파스 트리의 루트 노드에 해당 됨
  3. 고급 언어 프로그램에서 실행 코드까지의 변환 순서로 올바른 것은?  

    a. 어휘 분석, 구문 분석, 코드 생성

    • 어휘 분석(lexical analysis) 단계는 프로그램을 구성하는 문자들의 나열로부터 단어(token, 토큰)를 추출해 내는 과정임
    • 먼저, 빈 칸을 기준으로 단어를 구분하고, 구분 안의 각 단어를 이름, 숫자, 수식 기호 등으로 분류하는 것이 어휘 분석임
    • 어휘 분석의 결과로 나온 개개의 단어를 토큰(token)이라고 함
    • 구문 분석(syntax analysis) 단계는 어휘 분석의 결과로 나온 토큰들의 나열이 해당 프로그래밍 언어의 문법에 맞는 지를 확인하는 과정임
    • 코드 생성(code generation) 단계에서는 구문 분석의 결과로 변수, 상수, 제어의 흐름 등이 결정되면 이러한 각각의 명령어를 어셈블리어로 풀어 쓰거나 직접 기계어 이진 코드가 생성됨



정리 하기


  • 프로그래밍 언어의 파싱 트리
    • 단말 심벌(terminal symbol)
      • 문장을 이루는 단어들은 단말 심벌
    • 비 단말 심벌(non-terminal symbol)
      • 비 단말 심벌은 단말 심벌이 아니면서 복합적으로 나열된 단말 심벌과 비 단말 심벌의 조합
    • 생성 규칙(production rule)
      • 하나의 비 단말 심벌이 어떻게 다른 단말 심벌이나 비 단말 심벌을 대체할 수 있는지 정의하는 규칙
    • 시작 심벌(start symbol)
      • 가장 상위 계층의 비 단말 심벌로 보통 <문장>에 해당함
  • 프로그램에서 실행 가능 코드로의 변환
    • 어휘 분석
      • 프로그램을 구성하는 문자들의 나열로부터 단어(token, 토큰)를 추출해 내는 과정
    • 구문 분석
      • 어휘 분석의 결과로 나온 토큰들의 나열이 해당 프로그래밍 언어의 문법에 맞는 지를 확인하는 과정
    • 코드 생성
      • 구문 분석의 결과로 변수, 상수, 제어의 흐름 등이 결정되면 이러한 각각의 명령어를 어셈블리어로 풀어 쓰거나 직접 기계어 이진 코드가 생성
  • 프로그래밍 언어의 기본 공통 개념
    • 대입문(할당문)
      • 변수나 기억 장치 주소에 값을 저장하는 역할이며, l-value와 r-value로 구성됨
Contents

[컴퓨터과학 개론] 10강 - 컴퓨터 구조

[컴퓨터과학 개론] 12강 - 프로그래밍 언어