2014-03-27 2 views
1

이 문법을 상상 :- 들소

declaration 
    : declaration_specifiers ';' { /* allocate AST Node and return (1) */} 
    | declaration_specifiers init_declarator_list ';' { /* allocate AST Node and return (2)*/} 
    ; 
init_declarator_list 
    : init_declarator { /* alloc AST Node and return (3) */} 
    | init_declarator_list ',' init_declarator { /* allocate AST Node and return (4) */} 
    ; 

지금 ','토큰에 오류가 상상한다. 그래서 우리는 지금까지 있습니다

선언 -> declaration_specifiers init_declarator_list -> init_declarator_list ','/*error*/

은 무엇 여기됩니까?

들소는 (4) 코드를 실행합니까? 및 (2)? bison이 (4)를 실행하지 않으면 실행하지만 (2) $ 3 값은 무엇입니까? 어떻게하면 $ 변수의 기본값을 설정할 수 있습니까?

오류 발생시 생성 된 AST를 어떻게 삭제합니까?

답변

1

여기에 몇 가지 질문이 있습니다.

Bison은 현재 미리보기 토큰에 대한 작업 (이동 또는 축소)이없는 구문 분석 상태에 있기 때문에 오류를 감지합니다. 귀하의 예에서 ','을 이동 한 후 상태가 init_declarator_list 일 것입니다.이 상태에서는 FIRST (init_declarator)의 토큰 만 유효하므로 다른 토큰이 있으면 오류가 발생합니다.

해당 규칙이 축소되면 bison 코드의 작업이 실행되므로 action (4)이 호출되지 않습니다. 즉, 해당 규칙을 축소 할만큼 멀리는 가지 못합니다. 액션 (3)은 해당 규칙이 감소되었을 때 실행되며, 이는 ,이 오류가 감지 된 상태로 변경되기 전에 발생했습니다.

오류가 발생하고 (오류 메시지와 함께 yerror를 호출 한 후) 구문 분석기는 스택에서 벗어난 상태를 팝핑하여 복구하려고 시도하며 특수한 error 토큰을 이동할 수있는 것을 찾습니다. 상태를 팝하고 버리면 해당 상태에 해당하는 기호에 대해 %destructor 액션이 호출되므로 필요할 경우이를 사용하여 메모리를 정리할 수 있습니다.

경우에 따라 오류 규칙이없는 것처럼 보이므로 오류 토큰을 이동할 수있는 상태가 없습니다. 그래서 모든 주를 띄울 것이고, 그리고 나서 yyparse로부터 실패를 돌려 줄 것입니다. 오류를 이동할 수있는 상태를 찾으면 오류 팝핑이 중지되고 오류 토큰을 이동하고 오류 복구 모드에서 파싱을 계속 시도합니다. 오류 복구 모드에서 마지막으로 오류가 발생한 이후로 이동 한 토큰 (오류 토큰 제외)의 수를 계산합니다. 다른 오류가 발생하기 전에 3 개 미만의 토큰을 이동 한 경우 새 오류에 대해 yyerror가 호출되지 않습니다. 또한 0 토큰을 이동 한 경우 현재 상태에서 처리 할 수있는 입력 토큰을 찾을 때까지 (토핑 상태가 아닌) 입력 토큰을 읽고 버려서 오류를 복구하려고 시도합니다. 토큰을 버리면 해당 토큰에 대해 %destructor이 호출되므로 다시 정리해야하는 모든 것을 정리할 수 있습니다.

마지막 질문에 대답하기 위해 오류가 발생하면 %destructor 선언을 사용하여 물건을 삭제할 수 있습니다. %destructor은 들소 조치에 전달되지 않고 버려진 각 항목에 대해 정확히 한 번만 호출됩니다. 조치에 전달 된 항목 (조치에서 $1, $2 ...)은 호출되지 않으므로 조치 후 필요하지 않은 경우 해당 항목을 삭제해야합니다.

2

bison은 작업의 생산량이 감소되었을 때만 작업을 실행합니다. 즉, error 생산물이 아닌 경우에는 일치하는 양식이 사용 된 경우가 아니면 입력 내용이 정확히 일치해야합니다. (아래를 보라.) 그래서 액션이 수행되면, 터미널과 비 - 터미널과 관련된 다양한 의미 론적 값은 렉서 또는 각각의 행동의 결과라는 것을 확신 할 수있다.

그러나 오류 복구 중 bison은 자동으로 스택에서 의미 론적 값을 삭제합니다. 합리적으로 최근의 들소 버전을 사용하면 %destructor 선언을 사용하여 값을 삭제할 때 수행 할 작업을 지정할 수 있습니다. 당신은 유형 또는 기호 중 하나 소멸자를 지정할 수 있습니다. (자세한 내용은 bison manual 참조) (모두 또는하지만, 당 기호 소멸자가 우선합니다.)

%destructor 조치가 실행됩니다 때마다 bison폐기 의미 론적 값. 대충 말하면, 의미 적 값을 버리는 것은 프로그램이 의미 적 가치를 다룰 기회를 결코 얻지 못했음을 의미합니다. 생산량이 감소 할 때 스택에서 갑자기 꺼내 진 값은과 관련된 명시 적 동작이 없더라도 에 적용되지 않습니다. "버려진"의 완전한 정의는 앞에서 언급 한 들소 설명서 섹션의 끝에 있습니다.

오류 프로덕션이 없으면 전체 스택과 미리보기 기호 (bison은 자동으로 수행함)를 삭제 한 다음 구문 분석을 종료하는 것 외에는 오류 복구가 거의 불가능합니다. 문법에 오류 프로덕션을 추가하여 조금 더 효과적으로 작업 할 수 있습니다. 오류 생성에는 특수 토큰 error이 포함됩니다. 이 토큰은 다른 가능한 일치가없는 경우 정확하게 빈시 v 스를 일치시킵니다. 일반 제작물과 달리 오류 제작물을 즉시 볼 필요는 없습니다. bison은 전환이 error 인 상태를 찾거나 스택의 끝에 도달 할 때까지 스택에서 상태 (및 해당 값)를 삭제합니다. 또한 오류 생성에서 error 다음의 터미널은 미리보기 토큰 일 필요는 없습니다. bison은 오류 생성을 계속할 수 있거나 입력의 끝에 도달 할 때까지 미리보기 토큰 (및 해당 값)을 삭제합니다. 과정에 대한 더 자세한 설명은 handy manual을 참조하십시오 (또는 근처에 사본이있는 경우 드래곤 서적에 대한 내용을 읽으십시오).