프로그래밍[Univ]/프로그래밍 언어론

[프로그래밍 언어론] 모호함 / EBNF

Cloud Travel 2011. 9. 26. 15:46
룰을 통해서 문법을 생성함에 따라서 모호함이 발생한다. 이러한 모호함은 다음의 과정에 의해 지울수 있다.

일단 이전에 보았던 수학 기호에 대한 모호함이 발생 했을 시에 대해서 한번도 보고 가도록 하자.

1. 수학기호에 대한 모호함이 발생

 수학기호에 대해서 모호함이 발생했을 때에는 수학기호를 우선순위에 의해서 나눠서 생각한다. 

 또한 우선순위가 낮은 것부터 정의를 하기 시작한다.
  
 예를 들어 다음과 같은 문법이 존재한다고 한다.
 <expr> -> <expr>
 <expr> -> <expr> <op> <expr> | <id>
 <op> -> * | / | - | +  
 이 연산식을 모호함을 없앤다고한다면 연산 우선순위를 나눠 본다.
 + - 와 / * 로 나뉘는데 이것중 + - 의 우선순위가 더욱 느리다. 따라서 다음과 같이 정의가 된다.
 <expr> -> <expr> - <term> | <expr> + <term> | <term>
 <term> -> <term> * <id> | <term> / <id> | <id>
 로 수정을 하여 모호함을 없앨 수 있다.(자세한 과정은 이전에 소개 하였기에 생략하기로 한다)

 다음으론 문법적으로 모호함이 발생했을 때인데...
 
2. 문법적으로 모호함이 발생

 이 경우는 문법을 살표봐서 재설계 (redesign)을 해줘야한다.  

---------------------------------------------------------------------------------------------------

모호함을 없에는 방법에 대해서 대략적으로 알아보았다. 이젠 BNF로 쓰기에 모든 것을 설명하기 힘들다는 생각에 BNF를 확장한 Extended BNF(EBNF)에 대해서 알아 보기로한다.

1. EBNF(Extended BNF)
 

 - 선택적 사항을 표현
 ⓐ 선택적 문법 사항의 생성 / 생략이 가능한 부분의 탄생
 ⓑ '[]'기호를 사용하여 생략가능한 부분을 표시해준다.
  ex) Java에서 객체를 생성할시 생성자가 호출될 때 생성자 오버로딩에 의해서 여러방식으로 생성된다.
       예를 들어 ex라는 클래스의 생성자로 ex(), ex(int a), ex(int a, int b)...등을 가지고 있다고 하자.
       만약 이것을 BNF로 표현한다면 각 경우에 대해서 따로 룰을 정해줘야 할 것이다.
       이것을 EBNF를 써서 사용한다면 다음과 같이 작성이 가능하다.

       <proc_call> -> <id>([<expr_list>])
       의미는 다음과 같다. proc_call은 일정 identifier(이름)을 가지고
       '()'안에 expression을 가질수도 있고, 안 가질 수도 있다. 즉, ex(), ex(int a)등이 표현이 가능하다.

 - 중복된 표현의 중략
 ⓐ 공통된 부분을 가지고 중간에 특정한 값만 변할때 사용하는 표현
 ⓑ '()'기호안에 '|'를 사용하여 표현한다.
  ex) BNF에서  <expr> -> <expr> - <term> | <expr> + <term> | <term> 표현한 문법에서 연산자 '+'와 '-'를
       중간에 두고 <expr>과 <term>을 공통적으로 사용한다. 이 룰을 EBNF에서는 다음과 같이 중략이 가능하다.
       <expr> -> <expr> ( + | - ) <term> | <term> 
       어떤 expr은 expr과 term의 연산인데 사용되는 연산자는 +와 -중 하나이다. 또는 expr은 term으로 연결된다.

 - 반복적 표현
 ⓐ BNF에선 반복적 연산을 표현하기 위해서 재귀적 표현을 사용했다.
 ⓑ 재귀적 표현을 없에고 반복적 연산을 표현하기위해 '{}'를 사용해서 표현한다.
 ⓒ '{}' 기호 뒤에는 default 값으로 *이 들어간다(0번이상 실행).
     만약, 1번이상 실행으로 의미를 표현하고 싶으면 '{}' 기호 뒤에 + 기호를 사용하면 된다.
  ex) BNF에서 영어로 된 변수의 선언을 다음과 같이 정의했다. <ident> -> <letter><ident>|<letter>
       이 재귀적 표현은 <letter>가 1번이상 온다는 것을 의미한다. EBNF를 사용하면 다음과 같이 표현이 가능하다
       <ident> -> <letter>{<letter>} 또는 <ident> -> {<letter>}+


2. BNF > EBNF 변경
 

 - BNF를 EBNF로 변경시 좌결합 우결합으로 해결 못하는 것이 발생한다.
  > 반복적 실행을 할시 어디부터 실행하느냐??
 - 이 부분은 더 이상 프로그래머의 몫이 아니다. 이에 대해선 프로그램작성시 몇 있는 문법으로 지정이 가능하다.
  ex) 야크 라는 프로그램을 이용하면%associate (left or right)를 이용하여 값을 줄수 있다. 
  ex) <expr> -> <expr> + <term> | <expr> - <term> | <term>
        이 BNF expression은 <term>이 오거나 +또는 - 기호를 동반한 <term>의 반복이다.
        이를 EBNF로 바꾸면<expr>을 이용한 재귀표현이 사라지고 ( + | - ) <term>이 반복됨을 알 수 있다. 
        따라서, <expr> -> <term>{( + | - )<term>}이 된다.('좌 우선/우 우선'은 표시하지 않았다)


-----------------------------------------------------------------------------------------------------

논리적 모호함을 없에기 위한 재설계는 연습을 해야 하고...

BNF > EBNF 과정도 여러번 연습을 해야 익숙하게 될 것같다.. ㅠㅠ 

먼가 말로 설명하면 힘들어서 예를 이용해서 설명을 했다,