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>

     

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

    프로그래밍 언어 Names, Binding, Scopes  (0) 2020.05.01
    Lexical And Syntax Analysis  (0) 2020.04.30
    프로그래밍 언어 Semantic 표현  (0) 2020.04.29
    C언어의 문법  (0) 2020.04.13
    CFG (Context Free Grammar)  (0) 2020.04.13

    댓글

Designed by Tistory.