제로 컴 파일 러 (7): 의미 분석의 기호 표 의 데이터 구조

7211 단어
프로젝트 의 전체 코드 는 C2j - copiler 에 있 습 니 다.
머리말
기호 표 에 관 한 파일 은 모두 symboltable 가방 에 있 습 니 다.
앞에서 우 리 는 LALR (1) 유한 상태 자동 동기 와 reduce 정 보 를 완성 함으로써 문법 해석 표를 구축 하여 C 언어의 문법 해석 을 정식 적 으로 완성 했다.다음은 의미 분석 부분 에 들 어 가 는 것 이다. 두 번 째 편 에서 언급 한 것 과 마찬가지 로 의미 분석의 주요 임 무 는 기호 표를 생 성하 여 변수 와 변수의 유형 을 기록 하고 의미 에 부합 되 지 않 는 문 구 를 발견 하 는 것 이다.
설명 변수
C 언어 에서 변수 성명 에 대한 정의 에는 주로 두 가지 설명 이 있다.
  • 설명자 (Specifier) 설명자, 즉 C 언어 에 대응 하 는 설명 변수 유형 이나 static, extern 과 같은 키워드 (extern 과 같은 키 워드 는 이번에 실 현 된 컴 파일 러 에서 사용 되 지 않 았 습 니 다. extern 은 여러 소스 파일 의 컴 파일 과 링크 와 관련 될 수 있 기 때 문 입 니 다)
  • 수식 자 (Declarator) 수식 자 는 변수 명 이나 포인터 유형 을 대표 하 는 별표 로 배열 의 중 괄호 로 구성 되 어 있 으 며 수식 자 는 복잡 한 부분 에 속 하 며 수식 자 는 조합 할 수 있 기 때문이다.그래서 그룹의 수정자 에 대해 여러 개의 Declarator 를 만 들 고 순서대로 연결 할 수 있 습 니 다
  • 이렇게 하면 두 가지 유형 을 완성 할 수 있다. 이 두 가지 유형의 논 리 는 모두 비교적 간단 하 다.
    Declarator 클래스
  • declare Type: 현재 Declarator 가 포인터 인지 배열 인지 함수 인지 표시 합 니 다
  • numberOfElements, elements: 현재 유형 이 배열 이 라면 배열 의 요소 갯 수 와 배열 요소
  • 를 나타 낸다.
    public class Declarator {
        public static int POINTER = 0;
        public static int ARRAY = 1;
        public static int FUNCTION = 2;
    
        private int declareType;
        private int numberOfElements = 0;
    
        HashMap elements = null;
    
        public Declarator(int type) {
            this.declareType = type;
        }
        ...
    }

    specifier 클래스
    specifier 의 속성 은 비교적 많 지만, 뒤에 있 는 컴 파 일 러 는 int, char, void, struct 네 가지 유형 만 지원 할 수 있 습 니 다.
  • basic Type: 현재 변수의 유형 을 나타 내 는 데 사 용 됩 니 다
  • storageClass: 변 수 를 나타 내 는 저장 방식 (fixed, auto) 입 니 다. 여기 서 typedef 의 정보 도 여기에 놓 습 니 다. 즉, typedef 를 만나면 storageClass 는 TYPEDEF
  • 로 설 정 됩 니 다.
  • constantValue 와 vstruct: 이 두 가지 속성 은 비교적 특수 한 두 가지 속성 에 속 합 니 다. 이들 은 매 거 진 유형 과 구조 체 를 나타 내 는데 특수 한 이 유 는 그 후에 특수 처 리 를 해 야 하기 때 문 입 니 다.매 거 진 유형 을 만나면 basic Type 을 구성 하 는 것 과 같 습 니 다. CONSTANT 의 Specifier 입 니 다. 대응 하 는 값 은 constantValue 입 니 다
  • .
    public class Specifier {
        /**
         * Variable types
         */
        public static int NONE = -1;
        public static int INT = 0;
        public static int CHAR = 1;
        public static int VOID = 2;
        public static int STRUCTURE = 3;
        public static int LABEL = 4;
    
        /**
         * storage
         */
        public static int FIXED = 0;
        public static int REGISTER = 1;
        public static int AUTO = 2;
        public static int TYPEDEF = 3;
        public static int CONSTANT = 4;
    
        public static int NO_OCLASS = 0;
        public static int PUBLIC = 1;
        public static int PRIVATE = 2;
        public static int EXTERN = 3;
        public static int COMMON = 4;
    
        private int basicType;
        private int storageClass;
        private int outputClass = NO_OCLASS;
        private boolean isLong = false;
        private boolean isSigned = false;
        private boolean isStatic = false;
        private boolean isExternal = false;
        private int constantValue = 0;
        private StructDefine vStruct = null;
    }

    설명 기호 표
    앞에서 두 개의 변 수 를 설명 하 는 종 류 를 정 의 했 지만 이 두 가지 유형 만 으로 는 하나의 기 호 를 정확하게 표현 할 수 없 기 때문에 우 리 는 이 두 가지 유형 을 포장 하여 표 현 력 을 더욱 갖 도록 해 야 한다.
    프로 그래 밍 은 특정한 수요 에 따라 특정한 데이터 구 조 를 완성 하 는 경우 가 많 고 기호 표 는 컴퓨터 에서 본질 적 으로 변수의 데이터 구 조 를 묘사 하 는 데 만 사용 된다.
    이 데이터 구 조 는 기호 표 로 서 몇 가지 기본 적 인 조건 이 있다.
  • 속 도 는 기호 표 가 자주 삽입 되 고 찾 아야 하기 때문에 조회 와 삽입 속 도 는 충분히 빨 라 야 한다
  • .
  • 유연성 은 변수의 정의 가 복잡 할 수 있 기 때문에 여러 개의 수정자 에 지침 (long int, long doube *) 을 더 해 야 하기 때문에 디자인 에 있어 서 충분히 유연성 이 있어 야 한다
  • .
    컴 파일 러 를 배 우 는 것 은 진 선생님 의 수업 을 따 르 기 때문에 기호 표 의 디자인 도 선생님 의 디자인 을 따른다.
    위의 두 가지 조건 을 확보 하기 위해 서 우 리 는 체인 식 해시 표를 선택 하여 실현 한다.
    이 그림 은 내 가 인터넷 에서 찾 은 것 인 데, 실제로는 그렇게 복잡 하지 않다.
    모든 변 수 는 이 해시 표 에 저 장 됩 니 다. 같은 이름 의 변 수 는 해시 에 의 해 같은 곳 에 저 장 됩 니 다. 물론 서로 다른 역할 도 메 인 에 속 해 야 합 니 다. 서로 다른 역할 도 메 인 을 구분 하 는 것 은 이 그림 의 상단 부분 에 있 습 니 다. 같은 역할 도 메 인의 변 수 를 연결 합 니 다.
    symboltable.Symbol
    이 종 류 는 기호 표 안의 기 호 를 묘사 하 는 데 쓰 인 다.
    github 에서 원본 파일 을 다운로드 하면 뒤쪽 코드 생 성 에 필요 한 것 이 많 습 니 다. 무시 할 수 있 습 니 다.
    주요 속성 은:
  • level: 변수의 차원 을 나타 내 는 데 사용
  • duplicate: 동명 변수 인지
  • args: 이 기호 가 함수 명 에 대응 하면 args 가 가리 키 는 함수 의 입력 매개 변수 기호 목록
  • next: 다음 같은 차원 을 가리 키 는 변수 기호
  • public class Symbol {
        String name;
        String rname;
        int level; 
        boolean duplicate; 
        Symbol args; 
        Symbol next;  
    }

    이 럴 때 Symbol 에 이전의 Specifier 와 Declarator 를 더 하면 하나의 기 호 를 설명 할 수 있 습 니 다. 그러면 이 세 가지 종 류 를 연결 시 키 고 TypeLink 를 추가 해 야 합 니 다.
    TypeLink
    TypeLink 는 Specifier 나 Declarator 를 표시 합 니 다. 계승 으로 이 루어 지면 더 보기 좋 을 것 같 습 니 다.
    public class TypeLink {
        public boolean isDeclarator;
        /**
         * typedef int
         */
        public boolean isTypeDef;
        /**
         * Specifier or Declarator
         */
        public Object typeObject;
    
        private TypeLink next = null;
    
        public TypeLink(boolean isDeclarator, boolean typeDef, Object typeObj) {
            this.isDeclarator = isDeclarator;
            this.isTypeDef = typeDef;
            this.typeObject = typeObj;
        }
    
        public Object getTypeObject() {
            return typeObject;
        }
    
        public TypeLink toNext() {
            return next;
        }
    
        public void setNextLink(TypeLink obj) {
            this.next = obj;
        }
    
    }

    이렇게 Symbol 에 두 개의 속성 을 넣 어야 돼 요.
    type: Link Begin 과 type: Link End 는 변 수 를 설명 하 는 설명자 와 수정자 의 전체 링크 입 니 다. 즉, 전에 말 한 수정자 나 설명자 들 을 순서대로 연결 하 는 것 입 니 다.
    public class Symbol {
        String name;
        String rname;
        int level;  
        boolean implicit;  
        boolean duplicate; 
        Symbol args;  
        Symbol next;
    
        TypeLink typeLinkBegin;
        TypeLink typeLinkEnd;
    }

    예시
    이렇게 완성 하면
    long int (*e)[10];

    이렇게 표현 할 수 있어 요.
    Symbol
    declartor
    declartor
    specifer
    name:e
    declareType = PONITER
    declareType = array
    basicType = INT isLong = TRUE
    ->
    ->
    ->
    ->
    구조 체 기호의 정의
    StructDefine 이 파일 은 아직 말 하지 않 았 습 니 다. 이 파일 은 구조 체 를 묘사 하 는 데 사 용 됩 니 다. 구조 체 자체 의 복잡성 때문에 이 를 특수 처리 해 야 합 니 다. 그러나 구조 체 는 본질 적 으로 변수의 조합 이기 때문에 위의 방법 으로 설명 할 수 있 습 니 다.
  • tag: 구조 체 의 명칭
  • level: 구조 체 의 내장 층
  • Symbol: 구조 체 에 대응 하 는 변수
  • public class StructDefine {
        private String tag;
        private int level;
        private Symbol fields;
    
        public StructDefine(String tag, int level, Symbol fields) {
            this.tag = tag;
            this.level = level;
            this.fields = fields;
        }
    }

    예시
    구조 체 정의 의 예 를 보다.
    struct dejavidwh {
        int array1[5];
        struct dejavudwh *pointer1;
    } one;

    작은 매듭
    그래서 마지막 으로
    private HashMap> symbolTable = new HashMap<>();
        private HashMap structTable = new HashMap<>();

    기호 표를 묘사 할 수 있다
    symbol Table 의 key 는 변수의 이름 에 해당 하 며, 뒤의 Array List 는 같은 이름 의 변 수 를 저장 하고 있 습 니 다. Symbol 마다 next 포인터 가 같은 등급 의 다른 Symbol 을 가리 키 기 때문에 이러한 구 조 는 처음에 설명 한 해시 표 에 해당 합 니 다.
    이 절 은 주로 기호 표 의 데이터 구 조 를 묘 사 했 는데 두 가지 관건 은?
  • 변 수 를 설명 하기 위해 수정자 와 설명 자 를 정의 하여 변 수 를 설명 합 니 다
  • 관련 변 수 는 Symbol 링크 를 정의 하여 각 변 수 를 연결 합 니 다
  • 그리고 나의 github 블 로그:https://dejavudwh.cn/

    좋은 웹페이지 즐겨찾기