2017-05-10 16 views
0

아래 문법 스 니펫에서 $<nVal>4을 명시 적으로 사용해야하는 이유는 무엇입니까?들소 문법 % 유형 및 % 토큰

나는 %type <nVal> expr 라인이 필요하지 않으므로 간단하게 $4을 넣을 수 있다고 생각 했습니까?

내가 할 수 있도록 expr에 대해 다른 정의를 사용할 수 있습니까?

%union 
{ 
    int nVal; 
    char *pszVal; 
} 

%token <nVal> tkNUMBER 
%token <pszVal> tkIDENT 
%type <nVal> expr 

%% 

for_statement : tkFOR 
       tkIDENT { printf("I:%s\n", $2); } 
       tkEQUALS 
       expr  { printf("A:%d\n", $<nVal>4); } // Why not just $4? 
       tkTO 
       expr  { printf("B:%d\n", $<nVal>6); } // Why not just $6? 
       step-statement 
       list 
       next-statement; 

expr : tkNUMBER { $$ = $1; } 
; 

업데이트 RICI의 답변을 다음과 같습니다. 이유는 아래의 문법 코드에서 명시 적으로 $<nVal>4를 사용할 필요가

for_statement : tkFOR 
       tkIDENT { printf("I:%s\n", $2); } 
       tkEQUALS 
       expr  { printf("A:%d\n", $5 /* $<nVal>5 */); } 
       tkTO 
       expr  { printf("A:%d\n", $8 /* $<nVal>8 */); } 
       step-statement 
       list 
       next-statement; 

답변

2

입니다 : 이것은 지금 치료를 작동?

expr을 참조하려면 실제로 $5을 사용해야합니다. $4tkEQUALS이며 선언 된 유형이 없으므로 명시 적으로 입력해야합니다. $3은 이전 미들 룰 액션으로, $$이 해당 작업에 할당되지 않았기 때문에 값이 없습니다.

동일한 로직으로, 두 번째 expr$8입니다. $6은 값이없고 (유형이없는) 두 번째 midrule 조치입니다.

Bison manual 참조 :

중반 규칙 행동 자체가 규칙의 구성 요소 중 하나로 계산합니다. 이것은 동일한 규칙에 나중에 다른 액션이있을 때 (그리고 대개 마지막에 또 다른 액션이있을 때) 차이가납니다. 숫자를 n으로 사용하면 심볼과 함께 액션을 계산해야합니다. $n에 사용하십시오.

+0

감사합니다. - 당신은 완전히 맞습니다. – SparkyNZ

+0

나는 그것을 얻는다. "중간 규칙 동작"은 끝 부분에 나타나는 것이 아니라 규칙의 중간에 나타나는 중괄호 "얼룩"이다. 그래서 내가 마지막에 하나의 규칙을 가졌다면, 원래의 모든 번호가 작동했을 것입니다. 중간 룰 액션을 사용하여 번호 매기기에 중간 규칙 모양을 포함시켜야합니다. – SparkyNZ