2014-06-20 7 views
1

안녕 얘들 아 들소들에게 문제가 있습니다.이 코드 조각을 컴파일 한 후, 58 shift/reduce와 40 reduce/reduce conflicts를 얻습니다. 어떻게 그들을 제한 할 수 있는지, 또는 어떻게하는지에 대한 좋은 가이드를 알려주십시오. 미리 감사드립니다 !! 당신이 코드의 논리를 공부하는 시간을 해달라고해도 (T_get이 코드 위에 정의 된 토큰처럼, T_로 시작하는 모든)들소 줄이기/줄이기, 줄이기/줄이기

start:T_get G 
    |T_head G 
    |T_post G 
; 
G:url canon 
; 
url: T_http T_dslash T_host T_abs_path 
; 
canon:GH canon|RH canon|EH canon|MB 
; 
GH:T_con T_akt T_seq GH|T_date T_akt D GH|T_trans T GH| 
; 
D:T_day T_slash T_month T_slash T_year T_hour T_akt T_min 
; 
T:T_chunked |T_gzip |T_deflate 
; 
RH:T_acc T_akt T_seq RH|T_ref T_akt T_seq RH|T_user T_akt T_seq RH| 
; 
EH:T_content T_akt T_seq EH|T_exp T_akt T_seq EH| 
; 
MB:T_seq| 
; 


%% 
int main(){ 
yyparse(); 
} 

, 내가 어떻게 같이, 이러한 충돌에 대한 일반적인 도움을 주셔서 감사합니다 것입니다 그들은 생성 된 등

답변

4

bison의 -v 옵션을 사용하면 생성 된 파서의 모든 상태와 충돌을 제공하는 자세한 출력을 얻을 수 있습니다. 당신은 당신이 같은 상태의 것을 볼 수 있습니다 그렇게한다면 : 그것은 무엇을 말할 수 없다, 파서는 url를 본과 canon를 인식하고자 할 때 당신을 말하고있다

state 7 

    4 G: url . canon 

    T_acc  shift, and go to state 12 
     : 
    T_trans shift, and go to state 19 
    T_user  shift, and go to state 20 

    $end  reduce using rule 13 (GH) 
    $end  [reduce using rule 21 (RH)] 
    $end  [reduce using rule 24 (EH)] 
    $end  [reduce using rule 26 (MB)] 
    T_acc  [reduce using rule 13 (GH)] 
     : 

이를 - GH, RH, EH 또는 MB이 비어 있거나 비어 있지 않은 토큰을 인식하도록 토큰을 이동해야합니까? 모든 문법의 기본 모호함에서 오는

이 충돌 - 당신은 0 개 이상의 GH의 반복, RH 및/또는 EH로 구성 canon 규칙을 가지고 있고, 그 규칙은 각각 0 이상의 반복으로 구성 뭔가의. 그래서 파스 트리에 얼마나 많은 빈 물건을 넣을 지 알려주지 않습니다. (입력을 사용하지 않고 임의의 숫자를 추가 할 수 있기 때문에) 유사한 것들을 하나의 GH (또는 RH 또는 EH) 또는 여러 개의 다른 것들로.

이 문제를 해결하려면 원하는 것을 결정해야합니다. 대부분의 아마, 당신은 GH/RH/EH 구조의 그룹에 대한 관심이 없으며이 비어있는 걱정 할, 그래서 당신은이 규칙의 재귀 제거해야하지 않는다 : 이제

GH:T_con T_akt T_seq|T_date T_akt D|T_trans T; 
RH:T_acc T_akt T_seq|T_ref T_akt T_seq|T_user T_akt T_seq; 
EH:T_content T_akt T_seq|T_exp T_akt T_seq; 

의 각을 해당 규칙은 하나의 구문과 일치하며, 여러 규칙이있는 경우 canon 규칙에 따라 함께 그룹화됩니다. 이것은 모든 충돌을 해결하지만 여전히 잠재적 인 문제를 남깁니다 - 귀하의 canon 규칙은 재귀 적입니다. 규칙을 줄이기 전에 전체 입력을 스택에 빨아들입니다. 오른쪽 재귀의 경우 오른쪽에서 왼쪽으로). 규칙을 재귀 적으로 남겨두기를 원할 것입니다. bison의 일반적인 규칙은 입니다. 어떤 이유로 든 올바른 재귀가 필요하지 않는 한 항상은 재귀가 아니라 왼쪽 재귀를 사용합니다. 그러면 문법이 생깁니다 :

start : T_get G | T_head G | T_post G ; 
G : url canon MB ; 
url : T_http T_dslash T_host T_abs_path ; 
canon : canon GH | canon RH | canon EH | ; 
GH : T_con T_akt T_seq | T_date T_akt D | T_trans T ; 
D : T_day T_slash T_month T_slash T_year T_hour T_akt T_min ; 
T : T_chunked | T_gzip | T_deflate ; 
RH : T_acc T_akt T_seq | T_ref T_akt T_seq | T_user T_akt T_seq ; 
EH : T_content T_akt T_seq | T_exp T_akt T_seq ; 
MB : T_seq | ;