2013-02-06 25 views
13

Tôi là tác giả của doctest, nhanh chóng và bẩn doctests cho JavaScript và CoffeeScript. Tôi muốn làm cho thư viện ít bẩn hơn bằng cách sử dụng trình phân tích cú pháp JavaScript thay vì cụm từ thông dụng để định vị nhận xét.Thay thế nhận xét trong JavaScript AST bằng subtree bắt nguồn từ nội dung của nhận xét

Tôi muốn sử dụng Esprima hoặc Acorn phải làm như sau:

  1. Tạo một AST
  2. Walk cây, và cho mỗi nút bình luận:
    1. Tạo một AST từ bình luận văn bản của nút
    2. Thay thế nút nhận xét trong cây chính bằng cây con này

Input:

!function() { 

    // > toUsername("Jesper Nøhr") 
    // "jespernhr" 
    var toUsername = function(text) { 
    return ('' + text).replace(/\W/g, '').toLowerCase() 
    } 

}() 

Output:

!function() { 

    doctest.input(function() { 
    return toUsername("Jesper Nøhr") 
    }); 
    doctest.output(4, function() { 
    return "jespernhr" 
    }); 
    var toUsername = function(text) { 
    return ('' + text).replace(/\W/g, '').toLowerCase() 
    } 

}() 

Tôi không biết làm thế nào để làm điều này. Acorn cung cấp một số walker có kiểu nút và một hàm, và đi vào cây gọi hàm này mỗi khi một nút của kiểu xác định được gặp phải. Điều này có vẻ đầy hứa hẹn nhưng không áp dụng cho nhận xét.

Với Esprima tôi có thể sử dụng esprima.parse(input, {comment: true, loc: true}).comments để nhận các nhận xét, nhưng tôi không biết cách cập nhật cây.

+1

Bạn đã thử [JSShaper] (https://github.com/olov/jsshaper) chưa? –

+0

Tôi không biết về dự án đó. Có vẻ đầy hứa hẹn. – davidchambers

Trả lời

3

Hầu hết các trình phân tích cú pháp sản xuất theo AST đều vứt bỏ nhận xét. Tôi không biết Esprima hay Acorn làm gì, nhưng đó có thể là vấn đề.

.... trên thực tế, Esprima liệt kê chụp bình luận như một lỗi hiện tại: http://code.google.com/p/esprima/issues/detail?id=197

... Mã Acorn là ngay trong GitHub. Nó xuất hiện để ném bình luận đi, quá.

Vì vậy, có vẻ như bạn phải sửa lỗi phân tích cú pháp để nắm bắt các nhận xét trước tiên, tại thời điểm đó nhiệm vụ của bạn phải đơn giản hoặc bạn bị kẹt.

Bộ công cụ quản lý lại phần mềm DMS của chúng tôi có trình phân tích cú pháp JavaScript thu thập nhận xét, trong cây. Nó cũng có các bộ phân tích cú pháp substring, có thể được sử dụng để phân tích cú pháp văn bản nhận xét thành JavaScript ASTs. AST mới vào cây chính. Nếu bạn định thao tác với AST, khả năng chuỗi con này có khả năng quan trọng: hầu hết các trình phân tích cú pháp sẽ không phân tích các đoạn ngôn ngữ tùy ý, chúng chỉ có dây để phân tích "toàn bộ chương trình". Đối với DMS, không có nút nhận xét để thay thế; có những nhận xét liên kết với các nút AST, do đó quá trình ghép là một chút phức tạp hơn là chỉ "thay thế các nút nhận xét". Vẫn khá dễ dàng.

Tôi sẽ quan sát rằng hầu hết các trình phân tích cú pháp (bao gồm cả các tài nguyên này) đọc nguồn và chia nhỏ nó thành mã thông báo bằng cách sử dụng hoặc áp dụng tương đương với cụm từ thông dụng. Vì vậy, nếu bạn đã sử dụng chúng để định vị nhận xét (điều đó có nghĩa là sử dụng chúng để xác định các nhận xét * không * để vứt bỏ, ví dụ:, bạn cần phải nhận ra các chuỗi ký tự có chứa văn bản giống bình luận và bỏ qua chúng), bạn đang làm cũng như các trình phân tích cú pháp sẽ làm bất kỳ cách nào về mặt số tìm kiếm các chú thích. Và nếu tất cả những gì bạn muốn làm là thay thế chính xác nội dung của chúng, hãy lặp lại luồng nguồn với tiền tố nhận xét/hậu tố/* */tước sẽ thực hiện chính xác những gì bạn muốn, vì vậy tất cả máy phân tích cú pháp này có vẻ quá mức cần thiết.

2

Bạn đã có thể sử dụng Esprima để đạt được những gì bạn muốn:

  1. Phân tích các mã, có được các ý kiến ​​(như là một mảng).
  2. Lặp lại các nhận xét, xem nếu bạn quan tâm đến điều gì.
  3. Nếu bạn cần chuyển đổi nhận xét, hãy lưu ý phạm vi của nó. Thu thập tất cả các biến đổi.
  4. Áp dụng chuyển đổi trở về đầu để các dải ô không bị dịch chuyển.

Bí quyết ở đây không thay đổi AST. Chỉ cần áp dụng thay đổi văn bản như thể bạn đang thực hiện tìm kiếm thông thường thay thế trực tiếp chuỗi nguồn. Bởi vì vị trí của sự thay thế có thể thay đổi, bạn cần phải thu thập tất cả mọi thứ và sau đó làm điều đó từ người cuối cùng. Để biết ví dụ về cách thực hiện một phép biến đổi như vậy, hãy xem bài đăng trên blog của tôi "From double-quotes to single-quotes" (nó đề cập đến các trích dẫn chuỗi nhưng nguyên tắc vẫn giữ nguyên).

Cuối cùng nhưng không kém phần quan trọng, bạn có thể muốn sử dụng tiện ích cấp cao hơn một chút chẳng hạn như Rocambole.