룩어헤드 겨우겨우 조지고 생성기 만들고나서
충돌해결이 잘 이해가 가지 않아 냅두다가
갑자기 아이디어가 떠올랐음
yacc 에서 %left %right %nonassoc 을 적고
터미널을 적으면 나중에 충돌이 났을때
shift 냐 reduce냐 둘중 하나 골라야함
그래서 저런 지시자를 가지고 어떻게 선택을 하는지
구체적인 방법이 명확히 다가오지 않았는데
논리적으로 생각이 떠올랐음
1. reduce는 rule인데 무슨 터미널심볼이랑 비교해야하는가?
ㄴ 룰에서 나타났던 마지막 터미널 심볼을 고름
2. left rifht nonassoc 이든 터미널 처음 적은것부터
제일 마지막에 적은것 순서대로 우선순위증가
ㄴ 해당지시자 나오면 터미널 하나씩 1부터 score를 매겨서 계속 증가시키고 나중에 테이블 생성시 shift - reduce 충돌일때 높은쪽으로 선택함
3. 만일 score가 같으면?
여기까지 생각하다가 왜 left right nonassoc을 적는지
이해가갔음.. 단순한거였는데 왜 몰랐을까
1+2+3 은 같은 + 심볼로 충돌했을텐데 left에 적혀있어서
좌결합되고(1+2)+3, 실제 충돌시에는 reduce를 선택 먼저 묶어버림
a=b=c 는 반대로right에 적으며 shift를 시키고 a=(b=c) 로 우결합
nonassoc은 -1 같이 단항연산자에서 --1 같이 같은 심볼
나왔을때 아무것도 고르지 않고 에러처리를 해버리는거
머리가 나빠서 단순한거 가지고 개고생을 했네
%left %right %nonassoc을 전처리하도록 추가하고
%prec을 문법 마지막에 넣으고 새로운 연산자로 정의하도록
적게 되면 충돌이 해결되는 테이블생성기 완성...
딱 여기까지만 해야지... 힘들다
- dc official App
충돌을 해결하는게 아님. 충돌을 처리하는 방법을 정의할 뿐이지 어쨋든 충돌은 발생함 - return 0;
얘이 그게 맞는말임 - dc App
근데요 생각 1은 약간 아닌 것 같은데요 ㅇㅅㅇ - dc App
생성규칙 자체에 터미널 심벌과 비교가능한 순위를 줘서 해결하지 않나요? - dc App
첨에 그렇게 샌각했는데 yacc 문법은 %left 적고 연산자들(터미날) 만 적는식으로 되어있으니까 규칙 자체에 우선순위를 주는게 아닌거 같음 - dc App
전 YACC 잘 모르지만 %prec으로 생성규칙에 우선순위를 줄 수 있지 않나요? - dc App
%left 를 적는게 우선순위를 주는건디 대신에 shift reduce conflict 상황에서 shift 가 무조건 높다는거지 - return 0;
책에는 precedence와 associativity의 정보를 이용하여 다중으로 정의된 파싱 테이블에서 한 개의 행동을 선택한다고 적혀있는데요. precedence랑 associativity랑 다른 거 아닌가요? - dc App
어렵게 생각할 필요없어요. 그냥 터미널이랑 프로덕션룰에 left right 첨가해서 우선순위만 매겨주면되는건데