Trình soạn thảo dựa trên CDT, Phần 4 : Phân tích cú pháp CDT nâng cao và Mô hình đối tượng tài liệu kiên trì (Persisted Document Object Model-PDOM)

Hiểu việc lập chỉ mục CDT và PDOM

Bài viết này, là bài viết thứ tư trong loạt bài viết gồm năm phần "Trình soạn thảo dựa trên CDT" giới thiệu trình phân tích cú pháp thứ hai và lí tưởng hơn do công cụ phát triển C/C++ của Eclipse (CDT) sử dụng. Quá trình mới này lập cấu trúc thông tin của nó trong PDOM và cho phép lập chỉ mục, hoàn tất mã và hỗ trợ nội dung. Nếu bạn có ý định cải thiện hoặc mở rộng CDT cho các công cụ tùy chỉnh của riêng, thì cần hiểu biết về PDOM và về cách phân tích cú pháp mới.

Matthew Scarpino, Phát triển Java, Eclipse Engineering, LLC

Matthew Scarpino là nhà quản lý dự án và nhà phát triển Java tại Eclipse Engineering LLC. Ông là tác giả hàng đầu của SWT/JFace in Action và có đóng góp nhỏ nhưng quan trọng vào Standard Widget Toolkit (SWT). Ông thích nhạc dân gian Ailen, chạy maratông, thơ của William Blake, và Graphical Editing Framework (GEF).



10 09 2010

Lí do học về trình phân tích cú pháp khác

Liên kết ngoài là một trong nhiều tính năng của C/C++, làm cho khó phân tích mã. Dù bạn khai báo biến hay chức năng ở đâu, thì từ khóa ngoài cũng cho phép các tệp khác sử dụng nó mà không cần biết nơi nó được định nghĩa. Khi hiển thị sự phụ thuộc lẫn nhau, thì khung nhìn phác thảo của Eclipse, như ở bên trái của hình 1, là không hữu ích. Nó chỉ cho thấy các phần tử của các tệp nguồn đơn. Tuy nhiên ở bên phải, khung nhìn Index biểu diễn mỗi phần tử của mỗi tệp trong mọi dự án CDT. Nếu bạn đang cố gắng để các dự án được liên kết nhau, phức tạp, trở nên có ý nghĩa, thì tiếp cận thứ hai là sống còn.

Hình 1. Các khung nhìn Index và Outline
Các khung nhìn Index và Outline

Bạn có thể xây dựng khung nhìn Index bằng cách sử dụng trình phân tích cú pháp đã mô tả trong Phần 3, nhưng cần phải phân tích mọi tệp nguồn trong không gian làm việc của CDT bất cứ khi có bất kỳ mã nào bị sửa đổi. Điều này không thực tế.

Để làm cho các khả năng như của khung nhìn Index, các nhà phát triển CDT đã tạo quá trình phân tích cú pháp mới, lưu các kết quả của nó trong các tệp ánh xạ-bộ nhớ. Sự kiên trì này cho phép trình phân tích cú pháp truy cập các phần tử được lưu trữ trong một dự án trong khi chỉ phân tích các tệp vừa mới được thay đổi . Ngoài việc cung cấp khung nhìn Index, quá trình phân tích cú pháp được cải tiến này cũng làm cho các tính năng có thể thực hiện được, chẳng hạn như hoàn tất mã và hỗ trợ nội dung.

Cách trình phân tích cú pháp PDOM làm việc

Quá trình phân tích cú pháp mới không làm việc trao đổi trong phần 3 thành không thích hợp. Các trình phân tích cú pháp mới hoạt động căn bản giống như các trình phân tích cú pháp cũ. Chúng chứa các phương thức tương tự và tạo các cây cú pháp trừu tượng tương tự (ASTs). Tuy nhiên, nhiều quá trình mới đã thay đổi. Tôi sẽ tóm tắt hoạt động của chúng trong bốn bước:

  1. Bắt đầu công việc của trình chỉ mục
  2. Phân tích cú pháp lớp TranslationUnit
  3. Cập nhật PDOM
  4. Cấu trúc và lưu trữ PDOM

Bạn có thể thấy cách các khái niệm này được thực hiện trong mã, tôi đã cập nhật công cụ phát triển C/C++ lược giản (BBCDT) để tạo một chỉ mục của các phần tử dự án và hiển thị các loại nút đặc trưng. Để kích hoạt nó, tôi cập nhật lớp ASTAction trước đây để duyệt các phần tử trong AST và phần lưu trữ PDOM. (Xem mã trong mục Tải về ).

Bước 1: Bắt đầu công việc của trình chỉ mục

Khi trình cắm thêm lõi khởi động, nó tạo lớp PDOMManager để giám sát quá trình phân tích cú pháp mới và các phần còn lưu lại. Trình quản lý thực hiện một ít việc riêng, nhưng nó phản ứng khi các phần tử mới của CDT, đặc biệt là các đối tượng CProjectTranslationUnit xuất hiện trong vùng làm việc. Khi một đối tượng CProject mới được tạo, thì đối tượng PDOMManager tạo một trình chỉ mục để phát hiện và lưu trữ các phần tử trong các tệp nguồn của dự án.

Trình chỉ mục thực hiện IPDOMIndexer, nhưng lớp của nó phụ thuộc vào lựa chọn của người dùng trong CDT. Hình 2 cho thấy ba tùy chọn chỉ mục với mặc định là No Indexer. Khi bạn chọn No Indexer, chức năng PDOMManager tạo NullPDOMIndexer không thực hiện gì. Lớp PDOMManager tạo tính năng FastPDOMIndexer nếu bạn chọn Fast C/C++ Indexer và tính năng FullPDOMIndexer nếu bạn chọn Full C/C++ Indexer. Sau khi trình chỉ mục được tạo, trình quản lý lệnh cho nó bắt đầu việc xây dựng chỉ mục.

Hình 2. Các tuỳ chọn của trình chỉ mục
Các tuỳ chọn của trình chỉ mục

Mục tiêu của việc chỉ mục là ghi lại tất cả các phần tử có tên trong mã nguồn dự án và lưu trữ chúng với các dữ liệu liên quan với chúng. Đây là một quá trình phức tạp và có thể chạy ở chế độ nền, do đó nó được thực hiện như công việc của Eclipse. Cụ thể là trình chỉ mục tạo lớp Job có chỉ mục với ưu tiên của Job.LONG và thêm nó vào hàng đợi của nền.

Nếu dự án vừa được tạo, lớp Job không thực hiện được nhiều vì không có mã để lập chỉ mục. Tuy nhiên, nó xây dựng một đối tượng rất quan trọng đối với dự án, gọi là PDOM. Đối tượng này cung cấp các thường trình lưu trữ dữ liệu của trình chỉ mục trong PDOM.

Đối tượng PDOM không kiên định

Khi tôi viết về đối tượng này vào tháng Mười 2006, PDOM và việc phân tích cú pháp của nó chưa được hoàn thiện. Trên thực tế, nhiều điều hoang mang trên trang tin CDT sẽ cho biết nó không ổn định. Đây là tương lai của việc phân tích mã của CDT, tuy nhiên điều quan trọng là hiểu các khái niệm ngay cả các chi tiết thay đổi. Nó đóng một vai trò quan trọng đối với khả năng của các tính năng CDT (hỗ trợ nội dung, hoàn tất mã, lập chỉ mục, vv..) và vai trò này sẽ chỉ được mở rộng khi việc phát triển tiếp tục.

Không giống trình phân tích cú pháp trong phần 3, trình chỉ mục này không bắt đầu ngay lập tức hoặc tự động. Thay vào đó, PDOMManager chờ các thay đổi xảy ra với CProject, chẳng hạn tệp nguồn mới, bị sửa hoặc bị xóa. Khi phát hiện ra mỗi thay đổi, nó lệnh cho trình chỉ mục bắt đầu phân tích, và lúc này lớp Job của trình chỉ mục làm việc sốt sắng. Đặc biệt, nó tìm ra đối tượng TranslationUnit bị thay đổi và đối tượng ILanguage đại diện cho ngôn ngữ của mã nguồn của khối đơn vị. Rồi nó bắt đầu quá trình phân tích cú pháp bằng cách gọi phương thức ILanguage.getASTTranslationUnit().

Bước 2: Phân tích cú pháp đối tượng TranslationUnit

Trình phân tích cú pháp trong Phần 3 không phân biệt các ngôn ngữ lập trình. Nó tìm kiếm các phần tử của C và C++ và sử dụng chúng để tạo một AST chung. Quy trình mới này hoạt động khác hẳn. Mỗi TranslationUnit có một đối tượng ILanguage một điểm khác là quy định cụ thể cách các đơn vị cần được phân tích cú pháp. Nếu bạn muốn thêm một ngôn ngữ tùy chỉnh vào CDT, hãy tạo đối tượng ILanguage của riêng mình để bắt đầu. Rất may CDT cung cấp hai đối tượng theo mặc định: GCCLanguageGPPLanguage.

Tương tự, CDT cung cấp hai trình phân tích cú pháp mặc định, thực hiện đối tượng ISourceCodeParserGNUCSourceParserGNUCPPSourceParser. Quá trình phân tích cú pháp là tương tự như mô tả trong phần 3. Trình đọc mã tạo bộ đệm ký tự từ tệp nguồn, trình máy quét kết hợp các ký tự vào IToken và trình phân tích cú pháp kết hợp IToken vào IASTNode. Ngay cả các tên phương thức (translationUnit(), declaration(), statement() và các phương thức khác) đều giống nhau. Sau đây là những khác biệt chính giữa quá trình phân tích cú pháp mới và cũ:

  • Các trình phân tích cú pháp mới là một ngôn ngữ cụ thể, các nút mở rộng các đối tượng CASTNode hoặc CPPASTNode.
  • Các trình phân tích cú pháp mới luôn chạy ở chế độ COMPLETE_PARSE vậy chúng luôn phân tích cú pháp các chức năng bên trong.
  • Các trình phân tích cú pháp mới lưu trữ các thông tin phân tích cú pháp phụ (các vấn đề, các vị trí của nút) trong ILocationResolver thay vì trong một đối tượng gọi lại.
  • Các trình phân tích cú pháp mới chỉ xác định phạm vi của một phần tử khi được yêu cầu.
  • Nút trên cùng trong một AST mới là đối tượng IASTTranslationUnit, có cấu trúc có thể được duyệt bằng ASTVisitor.

Ghi nhớ: Trình phân tích cú pháp cũ trả về một đối tượng IASTCompilationUnit. Các trình phân tích cú pháp PDOM trả về các đối tượng IASTTranslationUnit hoặc chính xác hơn là CASTTranslationUnitCPPASTTranslationUnit.

Sự khác biệt thứ tư liệt kê trên là quan trọng. Trình phân tích cú pháp không thể xác định cách một phần tử được dùng trừ khi biết phạm vi của phần tử đó. Trình phân tích cú pháp cũ tạo phạm vi mức cao khi nó bắt đầu phân tích cú pháp với translationUnit(). Sau đó, nó chuyển phạm vi này cho các phương thức khác, chẳng hạn như declaration(), mà tạo và chuyển theo các phạm vi con khi cần thiết. Khi trình phân tích cú pháp cũ kết thúc, nó có phạm vi của mọi phần tử trong AST của nó. Trình phân tích cú pháp mới tạo một phạm vi đơn và không thay đổi nó trong suốt quá trình hoạt động của mình. Lí do là trình chỉ mục chỉ quan tâm đến một bộ các nút đặc biệt. Để giải thích điều này và các tính năng thú vị khác, tôi cần phải mô tả những gì trình chỉ mục thực hiện với AST của trình phân tích cú pháp và cách nó tương tác với PDOM.

Bước 3: Cập nhật PDOM

Sau khi trình chỉ mục nhận được IASTTranslationUnit, nó nhận khóa ghi trên PDOM và bắt đầu lưu lại dữ liệu của TranslationUnit. Trước tiên, nó gọi các phương thức IASTTranslationUnit.getIncludeDirectives()IASTTranslationUnit.getMacroDefinitions(). Rồi nó lưu tham chiếu đến tệp của đơn vị trong PDOM, cùng với các tham chiếu đến các hướng dẫn đã chứa và đến các định nghĩa hàm gộp. Các tham chiếu này lấy khuôn dạng PDOMFile có thể được lưu cùng phương thức PDOM.addFile().

Để tìm kiếm qua, hoặc duyệt, trình chỉ mục tạo đối tượng ASTVisitor mới và gọi đối tượng IASTTranslationUnit.accept(ASTVisitor). Mỗi đối tượng của IASTNode trong AST có phương thức accept() và mỗi phương thức hoạt động theo cùng một cách:

  1. Nó kiểm tra một trong các trường Boolean của đối tượng ASTVisitor để xác định xem trình duyệt có quan tâm đến việc duyệt nút này hay không.
  2. Nếu trình duyệt quan tâm, nút này gọi phương thức visit() của trình duyệt , trả về một trong ba giá trị sau:
    • PROCESS_SKIP -- Trình duyệt không quan tâm đến phần tử con của nút, do đó phương thức accept() trả về giá trị true.
    • PROCESS_ABORT -- Trình duyệt không quan tâm đến việc duyệt, vậy phương thức accept() trả về giá trị false.
    • PROCESS_CONTINUE -- Trình duyệt muốn duyệt các phần tử con của nút, do đó phương thức accept() tiếp tục bước tiếp theo.
  3. Nếu trường Boolean là false hoặc phương thức visit() trả về PROCESS_CONTINUE, thì phương thức accept() gọi phương thức accept() của mỗi phần tử con của nó, và chuyển việc duyệt như đối số của nó.

Lấy ví dụ: Nếu khai báo chức năng của C có trình chỉ định khai báo, chẳng hạn như typedef hoặc tĩnh (static), thì phương thức CASTFunctionDefinition.accept() tương ứng của nó kiểm tra trường shouldVisitDeclarations của trình duyệt. Nếu trường này là true, nó gọi phương thức visit() của trình duyệt. Nếu trường này là false hoặc phương thức visit() trả về giá trị PROCESS_CONTINUE, thì nút chức năng truy cập các phần tử con của nó và gọi phương thức CASTSimpleDeclSpecifier.accept(). Khi trình duyệt đến một trong các nút cuối, hoặc điểm kết thúc, thì đơn giản phương thức accept() trả về giá trị true.

Bảng 1 cho thấy các trường Boolean kiểm soát loại nút nào được phép gọi phương thức visit() của trình duyệt. Theo mặc định, tất cả chúng được thiết lập là false, vì vậy phương thức visit() là không bao giờ được gọi.

Bảng 1. Các trường ASTVisitor kiểm soát việc duyệt nút
shouldVisitNamesshouldVisitDeclarationsshouldVisitInitializers
shouldVisitDeclaratorsshouldVisitDeclSpecifiersshouldVisitExpressions
shouldVisitTypeIdsshouldVisitEnumeratorsshouldVisitTranslationUnit
shouldVisitParameterDeclarationsshouldVisitStatementsshouldVisitProblems

Cách tốt nhất để hiểu cách ASTVisitorlàm việc là xem một ví dụ. Liệt kê 1 cho thấy trình duyệt đượcPDOMFullIndexerJob sử dụng để tìm các nút IASTName Để duyệt các nút này, nó thiết lập shouldVisitNamesshouldVisitDeclarations có giá trị true.

Liệt kê 1. Trường ASTVisitor của đối tượng PDOMFullIndexerJob
ast.accept(new ASTVisitor() { 
   // Set the Boolean fields so that name and declaration nodes call visit() 
   { shouldVisitNames = true;
     shouldVisitDeclarations = true; 
   } 
   // Perform the visit 
   public int visit(IASTName name) {
      try { 
         IASTFileLocation fileloc = name.getFileLocation(); 
         if (fileloc != null) { 
            PDOMFile file = pdom.addFile(fileloc.getFileName()); 
            linkage.addName(name, file); 
         } 
         return PROCESS_CONTINUE; 
      } catch (Throwable e) { 
           CCorePlugin.log(e); 
           return ++errorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE; 
    } 
  }; 
});

Như bạn thấy, trình duyệt của trình chỉ mục chỉ quan tâm đến các đối tượng IASTName, là các nút được lưu trong PDOM. Chúng đại diện cho các trình định danh đạc biệt, chẳng hạn như tên các chức năng, các biến và kiểu dữ liệu liệt kê. Khi trình duyệt đến một trong các nút này, nó sẽ truy cập đối tượng PDOMFileđại diện cho tệp nguồn của tên. Sau đó nó sử dụng liên kết của PDOM (PDOMLinkage) để thêm đối tượng IASTName vào chỉ mục.

Trước khi IASTName có thể được lưu trữ, mối liên kết cần biết kiểu liên kết, hay buộc. Chẳng hạn cho dù nó là tên biến, chức năng, vv… Để tìm ra chúng, mối liên kết tìm phần cha của nút và phạm vi của nó. Với phạm vi này, mối liên kết cho thấy cách sử dụng tên gọi và đóng gói thông tin đó trong IBinding. Đây là lý do quá trình phân tích cú pháp mới quyết định về phạm vi sau khi phân tích cú pháp - nó chỉ quan tâm đến phạm vi của IASTName.

Để làm rõ tên và các buộc, tôi đã gỡ lỗi việc phân tích của CDT của chương trình Hello World và cung cấp lỗ hổng của AST như trong hình 3. AST chứa một đối tượng IASTDeclarationUnit đơn, đại diện cho chức năng main(). Đối tượng CASTFunctionDeclarator nắm giữ đối tượng CASTNameIBindingCFunction.

Hình 3. AST của Hello World
AST của Hello World

Mối liên kết làm IBinding thích nghi với PDOMBinding kiên trì và đối tượng IASTName thích nghi với đối tượng PDOMName. Trình kiến thiết đối với các đối tượng mới này truy cập PDOM để lưu trữ thông tin của chúng. Để thấy cách nó hoạt động, tôi cần phải sao lưu và giải thích cách PDOM hoạt động.

Bước 4: Cấu trúc của PDOM

Nếu bạn đã tạo một dự án CDT, tôi đề nghị bạn mở thư mục không gian làm việc của mình và thư mục .metadata/plugins/org.eclipse.cdt.core ở bên dưới nó. Tại đây bạn sẽ thấy tệp *.pdom cho mỗi dự án của bạn. Khi PDOM được tạo cho dự án, nó sẽ kiến thiết đối tượng cơ sở dữ liệu để quản lý việc lưu trữ mức thấp. Cơ sở dữ liệu xây dựng lớp RandomAccessFile mới và cho nó tên dự án và khoảng thời gian tính bằng mili giây - đây là những tệp *.pdom mà bạn thấy.

Java I/O và Java NIO

Hầu hết các thường trình vào/ra của Java™ mà tôi thấy vẫn còn sử dụng giao diện chương trình ứng dụng (API) của Java I/O. Giao diện này chuyển dữ liệu theo các dòng byte, cung cấp các đối tượng InputStream, OutputStream, WriterReader. Việc này là tốt khi hiệu năng chưa đặt ra. Các lớp trong API của Java I/O mới (NIO) chuyển dữ liệu bằng các phương pháp hiệu quả, chuyển lượng lớn như hệ điều hành của bạn. Điều này không chỉ quan trọng đối với các tệp nhỏ, mà còn tạo sự khác biệt lớn khi kích thước tệp gần bằng kích thước của các trang của hệ điều hành (ví dụ: 2 KB, 4 KB, 8 KB). Không phải ngẫu nhiên cơ sở dữ liệu khởi chạy các tệp *.pdom với kích thước 16 KB.

Trong CDT, bộ đệm quan trọng nhất của Java NIO là MappedByteBuffer, được tạo ở phía trên của một đối tượng RandomAccessFile hiện có. Việc truy cập tệp bình thường yêu cầu bộ nhớ đệm, phân bố vùng lưu trữ heap và các thường trình vào/ra tệp. Mặt khác, các MappedByteBuffer tức khắc được cập nhật bởi bộ điều khiển bộ nhớ ảo, và bộ nhớ không tác động đến vùng lưu trữ heap của Java. Cuối cùng, vì MappedByteBuffer nằm ở bên ngoài bộ nhớ xử lý, nên nhiều quá trình xử lý có thể truy cập đồng thời chúng một cách hiệu quả. Tuy nhiên, bởi vì nó hoạt động rất chặt chẽ với hệ thống điều hành, nên hành vi của nó phụ thuộc nhiều vào hệ điều hành hơn các thường trình I/O của Java.

Cơ sở dữ liệu này có nhiều điểm chung với các cơ sở dữ liệu thông thường, chứ không chỉ cùng tên. Nó phân chia bộ nhớ thành các bản ghi có chiều dài thay đổi, gồm các khối 16-byte. Mỗi bản ghi đại diện cho một PDOMNode khác nhau, chẳng hạn như đối tượng PDOMLinkage hoặc PDOMBinding. Để có thể truy cập bộ nhớ, nó cung cấp các phương thức cho phép đặt và thiết lập đối với số nguyên ( int), ký tự ( char), và byte.

Để đọc và ghi tệp có hiệu quả nhất có thể, cơ sở dữ liệu sử dụng một mảng lớn thông tin (Chunk), cho phép quản lý đối tượng MappedByteBuffer tại tệp *.pdom. Khi cơ sở dữ liệu tạo tệp này, nó đặt kích cỡ của tệp là 16 KB và đặt Chunk đầu tiên vào mảng tại bộ đệm. Cơ sở dữ liệu tạo các chunks có kích thước 16 KB khác khi chỉ mục đòi hỏi nhiều bộ nhớ hơn.

Đối tượng đầu tiên được bổ sung vào cơ sở dữ liệu là PDOMLinkage. Các mối liên kết mới được bổ sung vì ngôn ngữ mới được dùng trong dự án. Khi trình kiến thiết của nó được gọi, thì đối tượng PDOMLinkage:

  • Đặt kích thước cho bản ghi ban đầu của nó là 24 byte.
  • Lưu giá trị 0 để đại diện cho kiểu của nút (liên kết).
  • Lưu giá trị 0 để chỉ ra rằng nó không có nút cha.
  • Lưu kích thước của bộ nhớ cần thiết để lưu trữ tên của liên kết.
  • Định vị trí cho bộ nhớ và lưu trữ tên của liên kết.
  • Lưu kích thước của bộ nhớ cần thiết để lưu trữ ID của liên kết.
  • Định vị trí cho bộ nhớ và lưu trữ ID của liên kết.
  • Lưu kích thước của bản ghi của nó tại một địa chỉ đặc biệt, nếu đây là liên kết của dự án đầu tiên. Nếu nó không phải là liên kết dự án đầu tiên, thì nó tìm thấy địa chỉ kế tiếp có sẵn và lưu kích thước tại địa chỉ đó.

Việc xác định vị trí của bộ nhớ được thực hiện bởi Database.malloc(int size), đối tượng này bắt đầu bằng cách xác định số lượng tối thiểu các khối cần thiết để cung cấp bộ nhớ yêu cầu. Nếu không có đủ bộ nhớ có sẵn, nó tạo một Chunk mới. Nếu không, nó sẽ truy cập các Chunk có thể cung cấp bộ nhớ, xóa số lượng các khối yêu cầu, và trả về vị trí của khối được phân bổ đầu tiên.

Đối với các đối tượng khác, quá trình lưu trữ cũng tương tự, chẳng hạn như khi liên kết tạo PDOMBinding mới như một phần công việc lưu trữ một nút có tên. Nếu như buộc không có trong phạm vi của buộc khác, thì liên kết tự đặt nó như cha của buộc. Sau đó, trình kiến thiết PDOMBinding thiết đặt kích thước bản ghi ban đầu của nó là 24 byte và thực hiện hầu hết cùng các bước như liệt kê ở trên.

Đối tượng PDOMName hoạt động theo cách khác. Có ba cách để một tên có thể được liên kết với buộc của nó: định nghĩa, khai báo hoặc tham khảo. Khi PDOMName xác định mình đóng vai trò nào, nó cập nhật bản ghi của PDOMBinding. Sau đó, nó lưu vị trí của đối tượng PDOMFile mà tệp của nó chứa đối tượng đó, cùng với vị trí và chiều dài của đối tượng đó. Cuối cùng, nó điền đầy chỉ mục của tệp bằng cách thêm vị trí của các khối của mình vào PDOMFile.

Do mối quan hệ cha/con của PDOMNodes, nên chỉ mục tạo một cây tương tự như AST của trình phân tích cú pháp. Lần đầu phương thức PDOMLinkage.getIndex() được gọi, nó tạo đối tượng BTree bằng cách sử dụng cơ sở dữ liệu của PDOM và vị trí của khối gốc. Bạn có thể tìm kiếm qua cây này với IPDOMVisitor. This functions like the Nó hoạt động giống như đối tượng ASTVisitor với ba khác biệt quan trọng sau:

  • Nó không có trường Boolean - tất cả các nút được duyệt.
  • Nó chỉ sử dụng phương thức visit(IPDOMNode node) đơn, kiểm tra nút đã duyệt thuộc kiểu nào.
  • Nó chứa phương thức leave(IPDOMNode node) để ngừng tìm kiếm khi thấy một kiểu nút đặc biệt.

Bạn cũng có thể tìm kiếm qua PDOM bằng cách sử dụng các phương pháp tĩnh được cung cấp trong lớp DOMSearchUtil .


Cập nhật BBCDT

Tôi đã thêm các lớp PDOM và xem xét kích thước của ứng dụng, CDT lược giản có vẻ không thích hợp nữa. Tôi đã thiết lập đối tượng PDOMManager chỉ để tạo PDOMFullIndexer để lập chỉ mục dự án, do đó không cần ưu tiên hoặc trình miêu tả. Ngoài ra, tôi đã thay đổi đối tượng ASTAction để thực hiện hai nhiệm vụ: tìm kiếm qua đối tượng IASTTranslationUnit với BBASTVisitor và tìm kiếm qua PDOM với BBPDOMVisitor. Các lớp này nằm trong gói org.dworks.bbcdt.ui.action. Kết quả của việc nhấn đối tượng ASTAction được thể hiện trong hình 4.

Hình 4. Nội dung của chỉ số của BBCDT
Nội dung của chỉ số của BBCDT

Đối tượng BBASTVisitor tìm kiếm qua AST để tìm ra các đối tượng IASTNameIASTForStatement. Khi phát hiện một vòng lặp, nó sẽ hiển thị ba biểu thức: trình khởi chạy, điều kiện và phép lặp. Đối tượng BBPDOMVisitor tìm thấy các chức năng trong đối tượng BBPDOMVisitor và hiển thị số hiện tại.


Kết luận

Liên quan đến việc phân tích cú pháp, Java NIO, và việc truy cập cơ sở dữ liệu giả, không có câu hỏi về lập chỉ mục là quá trình phức tạp. Tuy nhiên, độ phức tạp này là cần thiết để cung cấp phân tích tổng thể và hiệu quả các mã và cách lưu trữ.

Bây giờ tôi đã giải thích về PDOM, đây là lúc để xem cách CDT áp dụng nó. Trong phần 5, tôi sẽ thảo luận về hoàn tất mã và hỗ trợ nội dung, bao gồm cả cách chúng hoạt động và cách chúng truy cập vào các chỉ mục của PDOM.


Tải về

Mô tảTênKích thước
BBCDT code for Part 4os-ecl-cdt4.zip512KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=518126
ArticleTitle=Trình soạn thảo dựa trên CDT, Phần 4 : Phân tích cú pháp CDT nâng cao và Mô hình đối tượng tài liệu kiên trì (Persisted Document Object Model-PDOM)
publish-date=09102010