1. Context-Free(BNF/EBNF)의 한계
- 오류에 대한 처리는 어떻게 할 것인가? ( ex//각각 변수의 타입사이의 차이의 표현 )
- 변수는 사용하기 이전에 선언 되어야 되는데 표현이 가능할가?
> 표현이 불가능하거나, 번거로운 것을 해결하기 위해 나온 것이 Attribute Grammars(AGs)이다.
2. AGs
- 특징
ⓐ 문법의 표현에 속성(Attribute) 값이 추가가 되었다.
> Synthesized Attribute : (Parse트리로 표현시)자식노드로부터 자신의 속성을 결정
자식노드의 평균 값, 최대/최소값 등 지정한 방법에 의해 속성을 자식으로부터 받는다.
> Inherited Attribute : (Parse트리로 표현시)부모나 형제 노드로부터 자신의 속성을 결정
부모노드의 속성을 물려받는 것이 일반적
ⓑ 함수(Function)이 추가 되었다.
> 여기서 함수란, 속성값 결정에 기준이 되는 것으로 어떻게 속성을 표현하는지에 대해서 지정하는 것이다.
ⓒ Predicate 추가됬다.
> 속성과 속성간의 관계를 정의해 준다.
ex) 다음 BNF를 타입(실수 or 정수)을 체크하여 계산이 가능하게 AGs를 작성하라.
<assign> -> <var> = <expr>
<expr> -> <var>+<var> | <var>
<var> -> a|b|c
이 문제의 예로 a = b + c를 표현한다고 해보자. 그렇다면 다음과 같은 것을 해야지 타입을 체크할 것이다.
ⓐ b와 c의 타입이 다를 경우 실수 타입으로 더한 값의 타입 지정
ⓑ b와 c가 같은 타입이면 그 타입으로 더한 값의 타입 지정
ⓒ = 이 왔을때 양쪽의 type이 같은지를 파악하여 같으면 실행, 아니면 error를 내라.
다음과 같은 특성을 적용시키는 AGs를 작성하면 다음과 같다.
1. 문법 규칙 : <assign> -> <var> = <expr>
문장 규칙 : <expr>.expected_type <- <var>.actual_type
//<expr>에 기대되는 타입이 <var>의 실제 타입과 같아야 한다.
2. 문법 규칙 : <expr> -> <var>[1] + <var>[2]
// <var>옆에 붙은 [1],[2]는 각각 var를 구분하기 위해서 사용한 일종의 구분자이다.
문장 규칙 : <expr>.actual_type <-
if ( var[1].actual_type = int ) and ( var[2].actual_type = int ) then int
//<var>[1]과 <var>[2]의 실제 타입이 모두 int일 경우 <expr>의 타입은 int이다.
else real //그렇지 않다면 real(실수)타입을 가진다.
end if
predicate : <expr>.actual_type == <expr>.expected_type
// <expr>의 지정된 타입과 새로 지정된(기대된) 타입이 같다.
3. 문법 규칙 : <expr> -> <var>
문장 규칙 : <expr>.actual_type <- <var>.actual_type //현재의 <var>타입이 <expr>타입이 된다.
predicate : <expr>.actual_type == <expr>.expected_type
// <expr>의 지정된 타입과 새로 지정된(기대된) 타입이 같다.
4. 문법 규칙 : <var> -> A|B|C
문장 규칙 : <var>.actual_type <- look-up(<var>.string)
//look-up 함수를 이용하여 변수이름을 얻고, 그 변수의 타입을 반환해받는다.
---------------------------------------------------------------------------------------------
* // 는 제가 의미로 만들어낸 주석입니다. 실제 문법적 규칙과 상의할 수 도 있습니다.
* <Name>.xxxx 여기서 xxxx는 사용자가 지정해준 특성이름으로 아무거나 와도 됩니다.
---------------------------------------------------------------------------------------------
> 그냥 한번 읽는 것은 이해가 안되므로 Parse트리에서 행하는 것을 보여 주도록 하겠습니다~
* 실행과정
1. a, b, c의 actual_type를 구한다(4번에 의해서)
2. b와 c의 type을 비교하여 <expr>의 actual_type를 구한다.(2번에 의해서)
3. <expr>의 expected_type와 actual_type가 같으면 성립, 다르다면 Error.(1번에 의해서)
- 오류에 대한 처리는 어떻게 할 것인가? ( ex//각각 변수의 타입사이의 차이의 표현 )
- 변수는 사용하기 이전에 선언 되어야 되는데 표현이 가능할가?
> 표현이 불가능하거나, 번거로운 것을 해결하기 위해 나온 것이 Attribute Grammars(AGs)이다.
2. AGs
- 특징
ⓐ 문법의 표현에 속성(Attribute) 값이 추가가 되었다.
> Synthesized Attribute : (Parse트리로 표현시)자식노드로부터 자신의 속성을 결정
자식노드의 평균 값, 최대/최소값 등 지정한 방법에 의해 속성을 자식으로부터 받는다.
> Inherited Attribute : (Parse트리로 표현시)부모나 형제 노드로부터 자신의 속성을 결정
부모노드의 속성을 물려받는 것이 일반적
ⓑ 함수(Function)이 추가 되었다.
> 여기서 함수란, 속성값 결정에 기준이 되는 것으로 어떻게 속성을 표현하는지에 대해서 지정하는 것이다.
ⓒ Predicate 추가됬다.
> 속성과 속성간의 관계를 정의해 준다.
ex) 다음 BNF를 타입(실수 or 정수)을 체크하여 계산이 가능하게 AGs를 작성하라.
<assign> -> <var> = <expr>
<expr> -> <var>+<var> | <var>
<var> -> a|b|c
이 문제의 예로 a = b + c를 표현한다고 해보자. 그렇다면 다음과 같은 것을 해야지 타입을 체크할 것이다.
ⓐ b와 c의 타입이 다를 경우 실수 타입으로 더한 값의 타입 지정
ⓑ b와 c가 같은 타입이면 그 타입으로 더한 값의 타입 지정
ⓒ = 이 왔을때 양쪽의 type이 같은지를 파악하여 같으면 실행, 아니면 error를 내라.
다음과 같은 특성을 적용시키는 AGs를 작성하면 다음과 같다.
1. 문법 규칙 : <assign> -> <var> = <expr>
문장 규칙 : <expr>.expected_type <- <var>.actual_type
//<expr>에 기대되는 타입이 <var>의 실제 타입과 같아야 한다.
2. 문법 규칙 : <expr> -> <var>[1] + <var>[2]
// <var>옆에 붙은 [1],[2]는 각각 var를 구분하기 위해서 사용한 일종의 구분자이다.
문장 규칙 : <expr>.actual_type <-
if ( var[1].actual_type = int ) and ( var[2].actual_type = int ) then int
//<var>[1]과 <var>[2]의 실제 타입이 모두 int일 경우 <expr>의 타입은 int이다.
else real //그렇지 않다면 real(실수)타입을 가진다.
end if
predicate : <expr>.actual_type == <expr>.expected_type
// <expr>의 지정된 타입과 새로 지정된(기대된) 타입이 같다.
3. 문법 규칙 : <expr> -> <var>
문장 규칙 : <expr>.actual_type <- <var>.actual_type //현재의 <var>타입이 <expr>타입이 된다.
predicate : <expr>.actual_type == <expr>.expected_type
// <expr>의 지정된 타입과 새로 지정된(기대된) 타입이 같다.
4. 문법 규칙 : <var> -> A|B|C
문장 규칙 : <var>.actual_type <- look-up(<var>.string)
//look-up 함수를 이용하여 변수이름을 얻고, 그 변수의 타입을 반환해받는다.
---------------------------------------------------------------------------------------------
* // 는 제가 의미로 만들어낸 주석입니다. 실제 문법적 규칙과 상의할 수 도 있습니다.
* <Name>.xxxx 여기서 xxxx는 사용자가 지정해준 특성이름으로 아무거나 와도 됩니다.
---------------------------------------------------------------------------------------------
> 그냥 한번 읽는 것은 이해가 안되므로 Parse트리에서 행하는 것을 보여 주도록 하겠습니다~
* 실행과정
1. a, b, c의 actual_type를 구한다(4번에 의해서)
2. b와 c의 type을 비교하여 <expr>의 actual_type를 구한다.(2번에 의해서)
3. <expr>의 expected_type와 actual_type가 같으면 성립, 다르다면 Error.(1번에 의해서)