2017-03-09 11 views
2

저는 들소를 처음 접했고 문법 분석 구문을 만들려고합니다. 지금 내가 해결할 수없는 변화/감소 confield에 직면하고 있습니다. 이것은 내 문법이다식 문법에서 시프트/감소 충돌 해결

%left "[" "(" 
%left "+" 

%% 

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 


expression : "(" expression ")" 
      | STRING_LITERAL  
      | INTEGER_LITERAL   
      | DOUBLE_LITERAL 
      | expression "(" expression_list ")" /*function call*/ 
      | expression "[" expression "]" /*index access*/ 
      | expression "+" expression   
      ; 

,하지만 변화는/그 두 가지 규칙 "(" expression ")"expression "(" expression_list ")"과 충돌을 감소에 직면하고있다 :

문법은 다음과 같다. 이 충돌을 어떻게 해결할 수 있습니까?

EDIT : 우선 순위 등반을 사용하여이 문제를 해결할 수는 있지만이 방법은 표현식 문법의 일부에 불과하므로 우선 순위 등반을 사용하여 표현식 문법의 크기가 폭발 할 것이므로 그렇게하지 않으려합니다.

+0

문법 전체에 해당하면 shift-reduce 충돌이 없습니다. 그러나, 나는 이것이 당신의 전체 문법이 아닌가 의심합니다. – rici

+0

와우 나는 지금 정말로 어리 석다. 나는 다른 규칙에 오타가있는 것을 발견했다. – Exagon

+0

그게 바로 "내 코드의 몇 줄"과는 다른 [mcve]를 요구하는 이유이다. [mcve]를 제작하면 문제를 명확히하는 데 도움이되어 문제를 해결할 수 있습니다. – rici

답변

2

제시된대로 문법에 shift-reduce 충돌이 없으므로 전체 문법을 일부 발췌 한 것만 가정합니다. 특히,이/쉬프트 정밀하게 될 실제 문법이 포함되어있는 경우 충돌이 언급 줄일 : 주어진 때문에

이 경우
%start program 
%% 
program: %empty 
     | program expression 

, 당신은 예를 들어, a(b)를 들어, 파서가 그것을 여부를 알 수없는 모호한으로 실행됩니다 단일 호출 표현식 또는 두 개의 연속 표현식, 첫 번째 단일 변수 및 두 번째 괄호 식입니다. 이 문제를 피하려면 표현식 (문장)을 구분하는 토큰이 필요합니다. 식 목록을 수 있습니다

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 

바람직 가능성이 없습니다 (f(,foo)에서와 같이) ,foo, 될 :

몇 가지 다른 문제가 있습니다. 더 나은 것이라고

arguments: %empty 
     | expr_list 
expr_list: expr 
     | expr_list ',' expr 

그리고 우선 순위는 아마도 거꾸로입니다. 대개는 호출 연산자와 인덱스와 같은 후위 연산자가 산술 연산자보다 더 긴밀하게 바인딩되기를 바란다. 그래서 결국 끝나야한다. 그렇지 않은 경우 a+b(7)(a+b)(7)이며 이는 파격적입니다.

+0

네가 맞아 미안해. – Exagon