0

들소에있는 ASN.1 컴파일러에 문제가 있습니다.들소 규칙 정의

OctetStringType : 
    OCTET STRING Constraint      { $$ = new  OctetString($3); } | 
    OCTET STRING '{' NamedOctetList '}' Constraint { $$ = new OctetString($6); } 
    ; 

I 새를 만들려고 :

A OCTET STRING (CONTAINING B) 

컴파일러가 B 함유 무시하고 B.로 언급 대신 OCTET STRING을 로 데이터를 참조 여기 현재 규칙이며 규칙 :

:

OctetStringType : 
    OCTET STRING '('ContentsConstraint')' {}| 
    OCTET STRING Constraint      { $$ = new OctetString($3); } | 
    OCTET STRING '{' NamedOctetList '}' Constraint { $$ = new OctetString($6); } 
    ; 
ContentsConstraint : 
    CONTAINING Type { } 
    ; 

나는 결과를 인쇄 할 때

OCTET STRING '('ContentsConstraint')' {printf("$$: %s\n",$$);} 

A가 있습니다. B에 액세스하려면 어떻게해야합니까? B에 액세스하려면 해당 규칙을 수정해야합니까?

+0

실제로 'OCTET STRING (B 포함)'은 'OCTET STRING'은 아니고'B' 타입이 아닙니다. 옥텟 스팅에서 전송 된 바이트들만이'B'의 인코딩입니다. – Henry

답변

1

(난 당신이 자신을 썼다 오히려 하나보다, 기존의 ASN.1 문법을 수정 있으리라 믿고있어.)

$$는 의미 작용에 의해 계산되는 의미 값입니다. 따라서

OCTET STRING '('ContentsConstraint')' {printf("$$: %s\n",$$);} 

은 전혀 의미가 없습니다. $$에 값을 할당하지 않았으므로 정의되지 않은 값으로 간주해야합니다.

실제적으로 bison/yacc 파서는 작업이 수행되기 전에 $$ = $1;이라는 할당을 효과적으로 수행했습니다 (이는 유용합니다. 이는 해당 작업을 수행 할 때 원하는 것을 쓸 필요가 없다는 의미이므로 유용합니다. 동작). 따라서이 경우 생산의 첫 번째 기호 (의미는 $1)의 의미 값을 인쇄합니다.이 기호는 터미널 OCTET입니다. 그러나 토큰 의 의미 값은입니다. 대부분의 파서에서는 키워드 터미널의 의미 론적 가치가 사용되지 않으므로 할당 할 필요가 없습니다.

대부분의 들소/Yacc에 파생 상품마다 의미 값이 컴파일러 경고를 (이전 버전이 작업을 수행하지 않았다)을 방지하기 위해 뭔가으로 초기화 될 수 있도록 몇 가지 문제로 이동하지만 뭔가가 지정되지 않습니다 및 마치 초기화되지 않은 것처럼 취급되어야합니다. 요약하면, 코드는 정의되지 않은 동작을 나타내며 아무 것도 인쇄 할 수 없습니다.

non-terminal ContentsConstraint의 의미 론적 값을 인쇄한다고 가정합니다. 비 터미널을 모두 정의하는 프로덕션에 대한 의미 론적 작업이 올바르게 값을 할당한다고 가정하면 ContentsConstraint이 규칙의 네 번째 토큰이므로 $4으로 액세스 할 수 있습니다. 즉, 적어도

ContentsConstraint : CONTAINING Type { $$ = $2; } 

은 그렇지 ContentsConstraint의 값이이 경우에서와 $1을,이다 기본 동작의 결과가 될 것입니다

ContentsConstraint : CONTAINING Type { } 

에 규칙 수정해야한다는 것을 의미 위와 같이 의미 론적 가치가 없습니다.

개념을 명확하게 할 수있는 예제를 참조하여 "시맨틱 액션"까지 적어도 처음 몇 페이지를 bison manual으로 읽는 것이 좋습니다. (전체 매뉴얼을 읽는 것은 너무 많은 시간을 소비하지 않아야하고 더 유용 할 것이지만, 요즘은 passer으로 간주됩니다.)