ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 구문 분석
    CS/Compiler 2023. 10. 7. 15:17

     컴파일러의 전반부 구조를 3단계로 나눈다면,

    1. 어휘(lexical) 분석

    2. 구문(syntax) 분석

    3. 의미(Semantic) 분석

    으로 구분할 수 있다고 하였다.

     

    오늘은 두 번째 단계인 구문 분석에 대해 알아보자.

    어휘분석 단계에서는 정규표현식으로 기술하고, 상태전이도를 따라가며 판별하여 토큰을 구분하였다.

     

    구문분석 단계에서는, 이 토큰들을 파스트리로 나타내고자 하는 것이 목표이다.

     


    CFG(Context Free Grammar)

     

    CFG는 언어의 문법을 정의하는 일반적인 방법으로, 표현된 문법으로 인식기를 손쉽게 구현할 수 있게된다.

    CFG의 문법은 아래와 같이 네 종류의 집합으로 표현할 수 있다.

     

    G(문법) = (N,T,P,S)

     

    1. N  : non terminal 심벌 집합

    중간과정 심벌이다.

    • A, B, C와 같은 알파벳 시작 부분의 대문자로 나타내게 됨
    • S는 보통 시작 심벌(start symbol)을 나타낸다.
    • <stmt>와 같이 < >로 묶어서 나타내기도 함

     

    2. T : terminal 심벌 집합

    토큰과 비슷한 느낌이라 생각하면 되겠다.

    • a, b, c와 같은 알파벳 시작 부분의 소문자와 숫자 0,1,2,…,9
    • +, -와 같은 연산자 기호와 세미콜론, 콤마, 괄호와 같은 구분자
    • ‘if’ 또는 “then”과 같이 따옴표 사이에 표기된 문법 심벌

    3. P : 생성 규칙 집합

    • 예)

    S → T + T

    T → ‘0’

    T → ‘1’

    T → ‘2’

     

    • A→a1 , A→a2 , …, A→ak와 같이 생성 규칙의 왼쪽이 모두 A인 경우에, A→a1 |a2 |…|ak로 간단히 표기

    예) T → ‘0’| ‘1’| ‘2’

     

    4. S : 시작 심벌

    만약 아무런 언급이 없으면 첫번째 생성 규칙의 왼쪽에 있는 것이 시작 심벌


    그렇다면 input token stream이 주어졌을 때, 이 문장이 문법에 맞는지 어떻게 판단 할 수 있을까

    유도

    문법에서 언어를 생성하는 것이다.

    생성 규칙을 연속적으로 적용하여 Non Terminal을 확장함으로써 얻을 수 있다.

     

    예를 들어서,

    E -> E + E | E * E | (E) | a

    라는 문법이 있다고 할 때,

    (a+a) 라는 언어를 유도해내보자.

     E -> (E) -> (E+E) -> (a+E) -> (a+a)

    위와 같은 방식으로 유도해낼 수 있고, 이를 트리 형식으로 나타내면 유도트리라고 부른다.

     

    유도트리

     

    유도를 할 때, 오른쪽 심벌을 먼저 대치할지, 왼쪽 심벌을 먼저 대치할지에 따라

    좌측유도와 우측유도로 구분할 수 있다.

     

    만약 문법G에 의해 생성되는 어떤 문장이, 두 개 이상의 유도트리를 갖는다면(좌측유도트리와 우측유도트리가 다르다면),

    문법G는 모호한 문법이다.

     

     

     

    위와 같은 문법에서, a + a * a 를 유도해볼 때,

    좌측 유도와 우측 유도를 각각 해보면,

    위와 같이 서로 다른 트리가 나온다.

    직접 한번 해보아도 좋다.

    즉, 위 문법은 모호하다고 할 수 있는 것이다.

     

    그렇다면, 이런 모호성이 있는 문법을 어떻게 하면 해결할 수 있을까?

     

    모호성 해결 1 - 연산자 우선순위 도입

     

    연산자 우선순위를 도입한 동일한 문법을 만듬으로써 모호성을 해결 할 수 있다.

     

    연산자마다 새로운 Non terminal을 도입하고,

    Recursion을 left나 right 둘 중 하나만 두고,

    시작 심벌과 가장 가까운 쪽에 연산자 우선순위가 낮은 것을 두면 된다.

     

    아래 예시를 보며 이해해보자.

    위 문법은 아까 보았던, 서로 다른 유도트리가 생성되는 모호한 문법이다.

     

    이 문법을,

    이러한 형식으로 연산자 우선순위가 낮은 순서대로, 시작 심벌과 가까운 쪽에 놓는다면 모호성을 해결 할 수 있다.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.