[정수리] 클라잉(五)클라잉 렉서 코드 읽기 노트의 렉서를 깊이 연구하다
Clang의 Lexer 소스의 주요 위치는 다음과 같습니다.
clang/lib/Lex 주요 Lexer 코드입니다.
clang/include/clang/Lex 여기는Lexer의 헤더 파일 코드의 위치입니다.
또한 Lexer는 clangBasic 라이브러리를 사용하기 때문에 Lexer의 코드를 분석하려면 clangBasic(clang/lib/Basic)의 일부 코드도 사용할 수 있습니다.
먼저 렉서부터 시작해.
clang/include/clang/Lex/Lexer.hclang::Lexer:
00057 //===--------------------------------------------------------------------===//
00058 // Context-specific lexing flags set by the preprocessor.
00059 //
00060
00061 /// ExtendedTokenMode - The lexer can optionally keep comments and whitespace
00062 /// and return them as tokens. This is used for -C and -CC modes, and
00063 /// whitespace preservation can be useful for some clients that want to lex
00064 /// the file in raw mode and get every character from the file.
00065 ///
00066 /// When this is set to 2 it returns comments and whitespace. When set to 1
00067 /// it returns comments, when it is set to 0 it returns normal tokens only.
00068 unsigned char ExtendedTokenMode;
00069
00070 //===--------------------------------------------------------------------===//
이 구성원 변수는 문법 분석의 한 상태를 보존하고 그 값에 따라 0, 1, 2, 각각 정상적인 token만 되돌려주고comments로 되돌려준다.정상적인 토큰과 공백,comments, 정상적인 토큰을 되돌려줍니다.
다음은 이 구성원 변수를 조작하는 몇 가지 함수입니다. 기본적으로 값을 얻기, 설정하기, 재설정입니다.코드는 복잡하지 않습니다.
00162 /// isKeepWhitespaceMode - Return true if the lexer should return tokens for
00163 /// every character in the file, including whitespace and comments. This
00164 /// should only be used in raw mode, as the preprocessor is not prepared to
00165 /// deal with the excess tokens.
00166 bool isKeepWhitespaceMode() const {
00167 return ExtendedTokenMode > 1;
00168 }
00169
00170 /// SetKeepWhitespaceMode - This method lets clients enable or disable
00171 /// whitespace retention mode.
00172 void SetKeepWhitespaceMode(bool Val) {
00173 assert((!Val || LexingRawMode || LangOpts.TraditionalCPP) &&
00174 "Can only retain whitespace in raw mode or -traditional-cpp");
00175 ExtendedTokenMode = Val ? 2 : 0;
00176 }
00177
00178 /// inKeepCommentMode - Return true if the lexer should return comments as
00179 /// tokens.
00180 bool inKeepCommentMode() const {
00181 return ExtendedTokenMode > 0;
00182 }
00183
00184 /// SetCommentRetentionMode - Change the comment retention mode of the lexer
00185 /// to the specified mode. This is really only useful when lexing in raw
00186 /// mode, because otherwise the lexer needs to manage this.
00187 void SetCommentRetentionState(bool Mode) {
00188 assert(!isKeepWhitespaceMode() &&
00189 "Can't play with comment retention state when retaining whitespace");
00190 ExtendedTokenMode = Mode ? 1 : 0;
00191 }
00192
00193 /// Sets the extended token mode back to its initial value, according to the
00194 /// language options and preprocessor. This controls whether the lexer
00195 /// produces comment and whitespace tokens.
00196 ///
00197 /// This requires the lexer to have an associated preprocessor. A standalone
00198 /// lexer has nothing to reset to.
00199 void resetExtendedTokenMode();
raw mode:raw mode 시, ExtendedTokenMode = 2, Lexer는 공백, comments, 정상적인 tokens를 포함한 모든 것을 출력합니다
문자.Lexer의 상위 클래스:clang::PreprocessorLexer 클래스()에 구성원 변수가 있습니다.
00049 /// \brief True if in raw mode.
00050 ///
00051 /// Raw mode disables interpretation of tokens and is a far faster mode to
00052 /// lex in than non-raw-mode. This flag:
00053 /// 1. If EOF of the current lexer is found, the include stack isn't popped.
00054 /// 2. Identifier information is not looked up for identifier tokens. As an
00055 /// effect of this, implicit macro expansion is naturally disabled.
00056 /// 3. "#" tokens at the start of a line are treated as normal tokens, not
00057 /// implicitly transformed by the lexer.
00058 /// 4. All diagnostic messages are disabled.
00059 /// 5. No callbacks are made into the preprocessor.
00060 ///
00061 /// Note that in raw mode that the PP pointer may be null.
00062 bool LexingRawMode;
Lexer가 raw mode 에 있는지 여부를 나타냅니다.이 동시에 이곳의 주석도 raw 모델의 작용을 설명했다.clang::Lexer의 정의를 보면 clang::PreprocessorLexer의 하위 클래스이고 위의rawmodel 부분도clang::PreprocessorLexer 클래스의 코드를 인용했습니다. 아래는clang::PreprocessorLexer의 코드를 보십시오.
clang/include/clang/Lex/PreprocessorLexer.h
00022 namespace clang {
00023
00024 class FileEntry;
00025 class Preprocessor;
에서 알 수 있듯이clang::PreprocessorLexer는 상기 두 종류를 사용했고 헤더 파일의 구체적인 위치는 다음과 같다.00027 class PreprocessorLexer {
00028 virtual void anchor();
00029 protected:
00030 Preprocessor *PP; // Preprocessor object controlling lexing.
및00164 /// getFileEntry - Return the FileEntry corresponding to this FileID. Like
00165 /// getFileID(), this only works for lexers with attached preprocessors.
00166 const FileEntry *getFileEntry() const;
코드에서 알 수 있듯이 이 두 종류는 하나는 구성원 변수이고 하나는 구성원 함수의 반환 유형으로 사용된다.우리는 코드를 추적해서 이 두 종류의 구체적인 실현을 보았다.이 두 가지 유형의 구체적인 실현은FileEntry가 비교적 간단하고 끝까지 보기 쉽다.Preprocessor류는 비교적 복잡하고 관련 내용이 많기 때문에 여기서 분석을 하지 않습니다.후속으로 계속 분석하다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
vue 단일 페이지에 여러 개의 echarts 도표가 있을 때의 공용 코드 쓰기html에서: 데이터 처리는 말할 필요가 없다.응, 직접 그림을 그려: 공통 섹션: 이 페이지를 떠날 때 파괴: 추가 정보: Vue + Echarts 차트 표시 및 동적 렌더링 준비 작업 echarts 의존 설치 n...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.