몇 가지 기본적인 데이터 구조 구문 분석 : 0에서 컴파일러 (C)을 작성

에서 프로젝트에 대한 전체 코드 C2j - 컴파일러

사설

이 시리즈는 컴파일러, 알고리즘 등이 어떤 원리에 대한 기록이없는 매우 명확로 작성 용 도서의 원리를 알고 싶어를 쓰기 학습의 과정에서 일부 레코드로 자신을 계산하지만 나는으로 시작 지금 이미 작성의 근거가 사람들에게 책처럼 아직 완전한 독서 그것을 가지고까지 매우 아래로 볼 수 있습니다.

여덟 개 파일의 총에 가방을 구문 분석, 구문 분석 단계는 모든 것을 작성하는 것입니다

  • Symbols.java
  • Production.java
  • SyntaxProductionInit.java
  • FirstSetBuilder.java
  • ProductionManager.java
  • ProductionsStateNode.java
  • StateNodeManager.java
  • LRStateTableParser.java

에서 프로젝트에 대한 전체 코드 C2j - 컴파일러

초기화 구문을 SyntaxProductionInit

마지막 말에서, 심지어 자연스럽게 문장이 정확한지 여부를 확인 문법을 필요로하는, 즉, 적절한 구문 유도 주어집니다

모든 문법 초기화는 SyntaxProductionInit에서 이루어집니다

///EXT_DECL_LIST ->EXT_DECL_LIST COMMA EXT_DECL
right = getProductionRight(new int[]{Token.EXT_DECL_LIST.ordinal(), Token.COMMA.ordinal(), Token.EXT_DECL.ordinal()});
production = new Production(productionNum, Token.EXT_DECL_LIST.ordinal(), 0, right);
productionNum++;
addProduction(production, false);

예를 들어, 유도의 선언, 시작 심볼의 프로그램 전체 유도의 C 언어에 해당하는 변수에 따라 EXT_DEF_LIST이 주장의 목록, EXT_DEF_LIST가 여기에있다 -> EXT_DEF_LIST EXT_DEF 재귀 경우 남아있는 것, LR 구문을 처리 할 수 ​​있습니다에 관심을 지불 할 필요 이 전에 블로그에서 볼 수 있습니다.

예를 들어 EXT_DECL_LIST -> EXT_DECL -> 변수 이름의 VAR_DECL의 복수 + + 쉼표 선언 변수 선언문 이름이나 변수 이름의 변수 이름 선언 복수를 유도 할 수있다

VAR_DECL 식별자는 포인터 또는 다수 일 수있다

즉, 리프 노드로부터 유도 상수 판독 터미네이터, 최종적 시작 심볼을 도출하고, 상기 입력 스트림은 완료

/*
*   PROGRAM -> EXT_DEF_LIST
*
*  EXT_DEF_LIST -> EXT_DEF_LIST EXT_DEF
*
*  EXT_DEF -> OPT_SPECIFIERS EXT_DECL_LIST  SEMI
*             | OPT_SPECIFIERS SEMI
*
*
*  EXT_DECL_LIST ->   EXT_DECL
*                   | EXT_DECL_LIST COMMA EXT_DECL
*
*  EXT_DECL -> VAR_DECL
*
*  OPT_SPECIFIERS -> CLASS TTYPE
*                   | TTYPE
*                   | SPECIFIERS
*                   | EMPTY?
*
*  SPECIFIERS -> TYPE_OR_CLASS
*                | SPECIFIERS TYPE_OR_CLASS
*
*
*  TYPE_OR_CLASS -> TYPE_SPECIFIER
*                   | CLASS
*
*  TYPE_SPECIFIER ->  TYPE
*
*  NEW_NAME -> NAME
*
*  NAME_NT -> NAME
*
*  VAR_DECL -> | NEW_NAME
*
*              | START VAR_DECL
*
*/

유도 문법의 초기화 처리에서는 세 가지 데이터 구조 전체를 구축

private HashMap<Integer, ArrayList<Production>> productionMap = new HashMap<>();
private HashMap<Integer, Symbols> symbolMap = new HashMap<>();
private ArrayList<Symbols> symbolArray = new ArrayList<>();
  • 좌측 키, 즉 ProductionMap, 값, 대응하는 하나 개 이상의 생산의 유도 인
  • 마찬가지로 SymbolMap ProductionMap가 남아 키 유도는 우측 값은 하나 이상의 생산은

이면에 다른 영향을 미칠 것이며, 유사 기호 제조, 생산을 나타내는데 사용되지만, 조금 상이하고 상기 터미네이터를 포함하는,

//Symbols
public int value;
public ArrayList<int[]> productions;
public ArrayList<Integer> firstSet = new ArrayList<>();
public boolean isNullable;

비 터미널 심볼 경우, 빈 세트가,이 우리가 널 (NULL) 비단 비단 부르는 것을 추론 할 수있다

  • 기호는 각 개체가 다시 다른 역할이있을 것이다 매장을 symbolArray

생산 제품 카테고리

그것은 답을 추론 대응의 구문 생산의 무리, 생산 클래스가 생산을 표현하는 것입니다 구문에 검증 프로세스에 관해서

private int dotPos = 0;
    private int left;
    private ArrayList<Integer> right;
    private ArrayList<Integer> lookAhead = new ArrayList<>();
    private int productionNum = -1;

    public Production(int productionNum, int left, int dot, ArrayList<Integer> right) {
        this.left = left;
        this.right = right;
        this.productionNum = productionNum;
        lookAhead.add(Token.SEMI.ordinal());

        if (dot >= right.size()) {
            dot = right.size();
        }
        this.dotPos = dot;
}
  1. 좌우 좌우 토큰 전에 값을 나타내는 데 사용되는 생산이며
  2. 미래 예측의 내다 세트는 나중에 참조하는 데 사용
  3. 도스와 마찬가지로 세부에서의 사용 후 자동 장치 지원을 구성
  4. 주어진 경우 생산 productionNum 해당 번호 초기화 구문에서이 개수

개요

이 사람은 여러 데이터 구조, 이러한 데이터 구조는 이후 유한 상태 오토마타의 기초에 내장되어 소개합니다. 원래이 일에 작성된 상태 머신을 구축하고 싶었지만 추가 다음 경우 자동 장치는 다음 중 하나를 작성하는 건설 있도록 모듈의 너무 방대한 플러스 부분은 조금 흩어져 느끼지 않을 것입니다.

또한 내 GitHub의 블로그 : https://dejavudwh.cn/

추천

출처www.cnblogs.com/secoding/p/11367530.html