ABOUT ME

개발 블로그에요

Today
Yesterday
Total
  • 프로그래밍 언어 Syntax 표현(기술)
    프로그래밍언어 2020. 4. 27. 20:12
    728x90

    Terminologies

    - Alphabet

    - String

    - Language (알파벳으로 만들 수 있는 모든 String 의 집합)

    - Sentence : Language 의 한 String

    - Lexeme : 의미적 요소의 최소 단위

    - Token : lexeme 의 카테고리

    - Language recognizer / generator  (인식기, 생성기)

     

    Lexeme (어휘 항목) : 구문 기술이 아닌 어휘 명세에 의해 주어지는 것으로, literal, operator, special word 등으로 이루어짐

    즉 프로그래밍 언어는 문자가 아닌 Lexeme 으로 이루어졌다고 말할 수 있음

     

    프로그래밍 언어의 구문 기술에는 Lexeme 은 고려되지 않음

     

    Syntax (구조, 문법) : expression, statement, program units 의 형태

    Semantic (의미) : expression, statement, program units 의 의미

    Syntax와 Semantic 이 합쳐져야 비로소 언어를 정의할 수 있음 (어느 한가지 만으로는 완전히 정의가 불가능)

    Syntax 를 표현하는 방법

    CFG(Context Free Grammar)

    CFG = (N, T, P, S)

    N = Nonterminal symbols ( 변수 목록 )

    T = Terminal symbols ( 상수 목록 )

    P : Productions ( or Rules 규칙 )

    S : Start symbol

     

    A -> B

    B -> BB | 1

     

    BNF(Backus-Naur Form)

    사실 이 둘은 비슷함. BNF 는 다른 언어를 설명하는 메타언어

    <LHS> -> <RHS> 의 꼴

     

    <while-statment> -> while ( <expression> ) <statment>

     

    Derivation

    BNF나 CFG 의 규칙에 따라 주어진 문장을 만들어나가는 것을 Derivation 이라 함

    그렇게 만들어진 최종 구문을 Sentence 라고 함

    언어가 만들 수 있는 모든 Sentence 의 집합을 Language 라고 함

     

    <assign> -> <id> := <expr>

    <id> -> A | B | C

    <expr> -> <id> + <expr>

                     | <id> * <expr>

                     | ( <expr> )

                     | <id>

     

    위와 같은 언어가 있을 때 A := B * (A + C) 를 Derivation

     

    Leftmost derivation

    <assign> -> <id> := <expr>

                   -> A := <expr>

                   -> A := <id> * <expr>

                   -> A := B * <expr>

                   -> A := B * ( <expr> )

                   -> A := B * ( <id> + <expr> )

                   -> A := B * ( A + <expr> )

                   -> A := B * ( A + <id> )

                   -> A := B * ( A + C )

     

    Rightmost derivation

    <assign> -> <id> := <expr>

                   -> <id> := <id> * <expr>

                   -> <id> := <id> * ( <expr> )

                   -> <id> := <id> * ( <id> + <expr> )

                   -> <id> := <id> * ( <id> + <id> )

                   -> <id> := <id> * ( <id> + C )

                   -> <id> := <id> * ( A + C )

                   -> <id> := B * ( A + C )

                   -> <id> := B * ( A + C )

     

    정리

    Leftmost derivation 은 왼쪽부터 전개해 나가는거고, Rightmost derivation 은 오른쪽부터 전개해나가는것

     

    이러한 전개 과정은 Parse tree 로도 표현이 가능

     

    Amibuity

    하나의 sentence 를 만드는데 두 개 이상의 서로 다른 parse tree 가 만들어질 수 있는 Language를 ambiguious 하다. 라고 함

     

    어떤 언어가 모호함을 보이려면 단 하나의 sentence 라도 모호함을 보이면 되고,

    어떤 언어가 모호하지 않음을 보이려면 모든 sentence 가 모호하지 않음을 보여야 하므로 이는 굉장히 어렵다.

     

    연산자 우선순위

    Parse tree 로 그렸을 때 아랫쪽에 있을 수록 먼저 평가가 되므로 우선순위가 높다.

     

    따라서

    곱하기가 우선순위가 더 높은 경우

    <assign> -> <id> := <expr>

    <id> -> A | B | C

    <expr> -> <expr> + <term>

                   | <term>

    <term> -> <term> * <factor>

                   | <factor>

    <factor> -> ( <expr> )

                   | <id>

    더하기가 우선순위가 더 높은 경우

    <assign> -> <id> := <expr>

    <id> -> A | B | C

    <expr> -> <expr> * <term>

                   | <term>

    <term> -> <term> + <factor>

                   | <factor>

    <factor> -> ( <expr> )

                   | <id>

    Left recursive

    <assign> -> <id> := <expr>

    <id> -> A | B | C

    <expr> -> <expr> + <term>

                   | <term>

    <term> -> <term> + <factor>

                   | <factor>

    <factor> -> ( <expr> )

                   | <id>

    Right recursive

    <assign> -> <id> := <expr>

    <id> -> A | B | C

    <expr> -> <term> + <expr>

                   | <term>

    <term> -> <factor> + <term>

                   | <factor>

    <factor> -> ( <expr> )

                   | <id>

     

    C언어의 if-else 모호함

    <if-stat> -> if ( <expr> ) <statement>

                     | if ( <expr> ) <statement> else <statement>

     

    if ( a ) if ( b ) x := 1; else x := 2;

    if ( a ) if ( b ) x := 1; else x := 2;

     

    모호하지 않게 바꾸려면

    <stmt> -> <matched> | <unmatched>

    <matched> -> if (<logic_expr>) <matched> else <matched>

                        | any non-if statement

    <unmatched> -> if ( <logic_expr> ) <stmt>

                        | if ( <logic_expr> ) <matched> else <unmatched>

     

     

    EBNF(Extended BNF)

    []  :  옵션. 있어도 되고 없어도 되는 것들

    {}  :  반복. 1개는 무조건 있고, 여러 개 있어도 되는 것들

    (|) :  n 개 중 하나를 고르는 것

     

    EBNF 가 설명을 더 잘 하는 것은 아니고, 가독성과 작성력을 올려준 BNF 이다.

     

    BNF

    <expr> -> <expr> + <term>

                    | <expr> - <term>

                    | <term>

    <term> -> <term> * <factor>

                    | <term> / <factor>

                    | <factor>

    <factor> -> <exp> ** <factor>

                    | <exp>

    <exp> -> ( <expr> )

                    | <id>

    EBNF

    <expr> -> <term> { ( + | - ) <term> }

    <term> -> <factor> { ( * | / ) <factor> }

    <factor> -> { <exp> ** } <exp>

    <exp> -> ( <expr> ) | <id>

     

    '프로그래밍언어' 카테고리의 다른 글

    댓글

Designed by Tistory.