귀하의 질문은 AST 노드를 구축하는 것에 대해 이야기하지만, 설명의 본문에는 기호 테이블에 관한 내용이 담겨 있습니다. 이 아이디어는 동일하지 않습니다! AST는 프로그램의 구조를 나타냅니다. 기호 표는 표시되는 이름에 대한 추론을 나타냅니다.
기호 테이블에 따라 블록을 "입력"할 때 현재 범위를 밀고 나가는 것처럼 개념을 적용하면 개념적으로 블록 당 새로운 범위를 달성하므로 개념적으로 옳습니다.
문법 규칙의 어느 시점에서든 의미 론적 조치를 취할 수 있는지 확신 할 수 없기 때문에 YACC가 말한 것을 할 수 있다고 생각하지 않습니다. 규칙 전체에 작업을 첨부 할 수 있다고 생각합니다.이 작업은 규칙이 인식 ("축소")되었을 때만 실행됩니다. 그래서 이것을 정말로 원한다면, 의미 론적 행동을 삽입 할 수있는 기회를 창출하기 위해 문법을 구부리기를 원할 것입니다. 당신은 (나는 생각하지 않는다이 실제로 유효한 YACC 문법 당신의 스타일 다음) 규칙을 다시 작성하여이 작업을 수행 할 수 있습니다 :
compound_statement : block_start statement_list block_end ;
block_start = '{' pushScope() ;
block_end = '}' popScope();
내가 시작을 차단하고 대칭 적으로 종료 작업을 추가,하지만 당신은 할 수 있습니다 좀 더 음, 인색 (미소) : 원래 규칙에 하위 규칙을 추가하여 블록을 입력 한 후
compound_statement : block_start statement_list '}' popScope() ;
block_start = '{' pushScope() ;
가 진짜 비밀은 여기 감소/세만 틱 액션 실행 기회를 작성했다. 나는 종종 빈 규칙을 사용하여이 일을했습니다
compound_statement : '{' compound_statement_sub_rule block_start statement_list '}' popScope() ;
compound_statement_sub_rule = pushScope() ;
는이 작업을 수행하는 방법의 종류를 표시하는 데, 난 당신이 모든이 작업을 수행 할 수 있다고 생각하지 않습니다. 당신이하는 일은 파싱 과정에서 의미를 뒤죽박죽으로 다루는 것입니다. 이 경로를 따라 가면 식별자 작성/조회를위한 복잡한 동작으로 문법의 나머지 부분을 꾸미는 자신을 발견하게됩니다. 일반적으로 의미 론적 작업을 사용하여 구문 트리를 작성한 다음 구문 분석이 완료된 후 구문 트리를 이동하여 기호 테이블 구성/식별자 조회를 구현하는 것이 일반적입니다.
나는 그들이 바보 같다고 생각하든, 생각하지 않든, 많은 시간 동안 질문을하고 싶습니다. 그것은 멋지게 갚을 것이다.
-1 이렇게 수동으로 빈 규칙을 만드는 것은 무의미한 것입니다. yacc이 허용하면 모든 힘든 일을 처리 할 것입니다. 또한, 구문 지시 번역 (Aho의 저서)의 전체 요점은 구문 분석 트리를 작성하고 별도의 패스로 통과하는 오버 헤드를 피하기위한 것입니다. 따라서 이것이 Aho 클래스에 실제로 해당된다면, 그렇게하지 않을 수도 있습니다. –
@Chris Dodd : 그러면 yacc이 의미 론적 동작을 사용하여 더미 규칙을 삽입 할 것이라고 말하고 있습니까? 승인. 필자가 보았던 대부분의 LALR 파서 생성기는 그렇게 희귀하지 않기 때문에 여분의 툴링은 불필요 해 보인다. "구문 지시 번역"에 관해서는 당신이 맞습니다. 만약 그들이하는 일이라면 모든 것을 함께 짜 넣어야 할 것입니다. 합리적인 사람은 OP의 문제 문장을 해석 할 것입니다. "우리는 AST 생성을 위해 다음 코드를 고려하고 있습니다."는 구문 지시 변환을 수행하지 않았 음을 나타냅니다. "아호의 책"은 전적으로 구문 지향 번역에 관한 것이 아닙니다. –