2009-05-20 6 views
6

저는 YACC (실제로 Bison)에 문법을 쓰고 있습니다. 나는 shift/reduce 문제가 있습니다. 접미사 증가 및 감소 연산자가 포함 된 결과입니다. 다음은 문법의 아래 손질 버전 :후행 증가 연산자에서 YACC 시프트/감소 충돌을 수정하는 방법은 무엇입니까?

%token NUMBER ID INC DEC 

%left  '+' '-' 
%left  '*' '/' 
%right  PREINC 
%left  POSTINC 

%% 

expr: NUMBER 
|  ID 
|  expr '+' expr 
|  expr '-' expr 
|  expr '*' expr 
|  expr '/' expr 
|  INC expr %prec PREINC 
|  DEC expr %prec PREINC 
|  expr INC %prec POSTINC 
|  expr DEC %prec POSTINC 
|  '(' expr ')' 
; 

%% 

들소가 나에게 말한다 (12) 교대/갈등을 줄일 수 있습니다,하지만 난 후위 증가 및 감소를 위해 줄을 주석하는 경우, 그것을 잘 작동합니다. 누구든지이 갈등을 해결하는 방법을 알고 있습니까? 이 시점에서 LL (k) 파서 생성기로 이동하는 편이 훨씬 쉽습니다. LALR 문법은 항상 자연스럽게 작성하는 것처럼 보입니다. 또한 GLR을 고려 중이지만 좋은 C/C++ GLR 파서 생성기에 대해서는 잘 모릅니다.

+3

유권자가 적어도 이유를 제시한다면 나는 감사 할 것입니다 ... – Zifre

답변

3

옵션 섹션에 %glr-parser을 지정하면 Bison/Yacc에서 GLR 구문 분석기를 생성 할 수 있습니다.

+0

와우! 나는 그것을 알지 못했습니다 ... 나는 그것을 시도했지만, 여전히 원래의 문법과의 shift-reduce 충돌을 경험합니다. 나는 Bison의 GLR 알고리즘이 우선 순위와 잘 협조하지 않는다고 생각하지만 David Dolson의 답변과 함께 사용할 수 있습니다. – Zifre

+0

좋아요, 방금 David Dolson의 방법으로이 작업을 시도했지만 작동합니다! – Zifre

+1

-1 : GLR 모드를 사용하는 것은 좋은 해결책이 아닙니다. 모호성을 어떻게 든 해결해야하므로, 모호성을 해결하지 않으면 들소가 조용히 문법을 불만없이 받아 들여주고 런타임 오류가 발생하지 않으므로 문제를 해결했다고 생각하기 쉽습니다. –

0

더 많은 항목을 정의하고 싶습니다. % left, % right, % prec 물건은 필요 없습니다.

simple_expr: NUMBER 
| INC simple_expr 
| DEC simple_expr 
| '(' expr ')' 
; 

term: simple_expr 
| term '*' simple_expr 
| term '/' simple_expr 
; 

expr: term 
| expr '+' term 
| expr '-' term 
; 

이 방법으로 해결하십시오.

+1

나는 그 접근법을 이전에 시도해 봤지만 좋지 않습니다. 훨씬 복잡한 표현식 문법 (예 : C++과 같은)을 사용하면 수정할 필요가있는 작업을 정확히 이해하기가 어려워집니다. 우선 순위를 사용하는 것이 훨씬 깔끔한 IMO입니다. – Zifre

2

이 시도 :

%token NUMBER ID INC DEC 

%left  '+' '-' 
%left  '*' '/' 
%nonassoc '++' '--' 
%left  '(' 
%% 

expr: NUMBER 
|  ID 
|  expr '+' expr 
|  expr '-' expr 
|  expr '*' expr 
|  expr '/' expr 
|  '++' expr 
|  '--' expr 
|  expr '++' 
|  expr '--' 
|  '(' expr ')' 
; 

%% 

의 핵심은 비 연관로 후위 연산자를 선언하는 것입니다. 그렇지 않으면

++var++-- 
괄호는 변화를 최소화하기 위해 우선 순위를 부여 할 필요가

할 수있을 것입니다/

+0

사실, 보통의 C 행동에 대해'++ var ++ '를'++ (var ++)'로 해석하고 오류로 거부하지 않기를 원하기 때문에 (접미사가 접두어보다 우선 순위가 높다)'% right'가'% nonassoc' –

+0

또한''('')의 우선 순위는 여기에 관련된 충돌이 없기 때문에 무의미합니다 (예 : C 스타일의 함수 호출이나 캐스트 구문을 추가 한 경우). 그 경우에는'% left'이 아닌'% right'을 원할 것입니다. –

-1

선행 증가 및 후행 사업자 nonassoc 그래서 우선 순위 섹션에서 그 정의가 경고를 줄이고 규칙 만들기에 %prec

0

이 기본적인 문제를 사용하여 높은 이러한 연산자의 우선 순위는 당신이 INCDEC 토큰에 대한 우선 순위를 필요가 없다는 것입니다, 그래서 INC 또는 0 내다 관련된 모호성을 해결하는 방법을 알고하지 않습니다. 당신이 우선 순위 목록의 마지막에

%right INC DEC 

을 추가하면, 그것은 문제를 해결하고 당신도 모든 PREINC/POSTINC 물건을 제거 할 수 (당신은 unaries 높은 우선 순위와 접두사보다 높은 접미사가되고 싶어요) , 그것은 중요하지 않습니다.

관련 문제