Bất kỳ trình phân tích cú pháp PHP tốt nào được viết bằng PHP? [đóng cửa]


80

Tôi thực hiện rất nhiều thao tác và phân tích mã PHP. Thông thường tôi chỉ sử dụng Tokenizer để làm điều này. Đối với hầu hết các ứng dụng, điều này là đủ. Nhưng đôi khi phân tích cú pháp bằng cách sử dụng lexer không đủ tin cậy (rõ ràng).

Vì vậy, tôi đang tìm kiếm một số trình phân tích cú pháp PHP được viết bằng PHP. Tôi đã tìm thấy hnw / PhpParserkumatch / stagehand-php-parser . Cả hai đều được tạo ra bằng cách chuyển đổi tự động zend_language_parser.y thành tệp .y với PHP thay vì C (và sau đó được biên dịch thành trình phân tích cú pháp LALR (1)). Nhưng không thể làm việc với chuyển đổi tự động này.

Vì vậy, có bất kỳ trình phân tích cú pháp PHP tốt nào được viết bằng PHP không? (Tôi cần một cái cho PHP 5.2 và một cái cho 5.3. Nhưng chỉ một trong số chúng cũng sẽ là một điểm khởi đầu tốt.)


1
Mục tiêu của bạn là gì? Bạn đang cố gắng hoàn thành điều gì ở đây?
Charles

3
@Charles: Có nhiều thứ tôi sẽ sử dụng cái này. Chỉ cần bất kỳ thứ gì cần mã nguồn PHP trong đại diện AST;)
NikiC

1
@mario: Cái đó có rất nhiều thông tin. Nó thực sự chỉ được thiết kế cho nhiệm vụ trích xuất một số thông tin về tệp. Vì vậy, nó chỉ giữ những thứ như câu lệnh lớp, câu lệnh phương thức hoặc câu lệnh trả về, nhưng bỏ qua mọi thứ mà tôi thực sự quan tâm nhất: Đoạn mã.
NikiC

2
Tôi không nghĩ rằng bạn sẽ tìm thấy bất kỳ trình phân tích cú pháp ngôn ngữ quy mô lớn, mạnh mẽ nào được mã hóa bằng PHP. Không có lời kêu gọi nào cho nó.
Ira Baxter

4
Trong tuần trước, tôi đã tự viết phiên bản ban đầu của trình phân tích cú pháp: github.com/nikic/PHP-Parser Tôi đã thử nghiệm nó với cơ sở mã của mình và nó hoạt động tốt. Tôi sẽ làm việc để cải thiện các giao diện để nó thực sự có thể sử dụng được.
NikiC

Câu trả lời:


128

Sau khi không tìm thấy trình phân tích cú pháp hoàn chỉnh và ổn định ở đây, tôi quyết định tự viết một trình. Đây là kết quả:

PHP-Parser : Một trình phân tích cú pháp PHP được viết bằng PHP

Dự án hỗ trợ phân tích mã được viết cho bất kỳ phiên bản PHP nào giữa PHP 5.2 và PHP 7.1.

Ngoài trình phân tích cú pháp, thư viện còn cung cấp một số thành phần liên quan:

  • Biên dịch AST trở lại PHP ("in ấn đẹp")
  • Cơ sở hạ tầng để duyệt và thay đổi AST
  • Tuần tự hóa đến và từ XML (cũng như kết xuất ở dạng con người có thể đọc được)
  • Độ phân giải của các tên không gian tên (bí danh, v.v.)

Để biết tổng quan về cách sử dụng, hãy xem phần "Cách sử dụng các thành phần cơ bản" của tài liệu .


2
Điều này thật tuyệt! Bạn có kế hoạch để duy trì nó không?
MikeSchinkel

1
@NikiC Cảm ơn anh bạn! Đó là một thư viện tuyệt vời :-)
BVengerov

1
Chà, hỗ trợ PHP 7.1 vào đầu tháng 12 năm 11!
dotancohen

9

Đây sẽ không phải là một lựa chọn tuyệt vời cho bạn, vì nó vi phạm ràng buộc thuần PHP, nhưng:

Một thời gian trước, những người php-internals đã quyết định rằng họ sẽ chuyển sang Lemon làm công nghệ phân tích cú pháp của họ. Có một nhánh trong PHP svn repo chứa các thay đổi bắt buộc.

Họ quyết định không tiếp tục điều này nữa , vì họ thấy rằng dung dịch Lemon của họ chậm hơn khoảng 10-15%. Nhưng, chi nhánh vẫn ở đó.

Có một trình phân tích cú pháp Lemon cũ hơn được viết dưới dạng một phần mở rộng PHP. Bạn có thể làm việc với nó. Ngoài ra còn có gói PEAR này . Ngoài ra còn có gói chanh khác này (thông qua bài đăng trên blog này về PGN ).

Tất nhiên, ngay cả khi bạn làm cho nó hoạt động, tôi không chắc bạn sẽ làm gì với dữ liệu hoặc dữ liệu trông như thế nào.

Một lựa chọn kỳ quặc khác sẽ là Quercus , một triển khai PHP trong Java. Họ phải viết một trình phân tích cú pháp, có lẽ nó có thể đáng để điều tra.


Trước hết: +1 cho nghiên cứu sâu rộng. Vấn đề chính không phải là không có cách nào để xây dựng một trình phân tích cú pháp trong PHP. Bạn đã đề cập đến việc sử dụng ngữ pháp PHP Lemon và biên dịch nó. Thậm chí có thể dễ dàng hơn là sử dụng ngữ pháp yacc / bison "thực" (cũng có trình biên dịch cho điều đó). Vấn đề là hơn thế nữa, nó thực sự rất nhiều công sức để chuyển đổi mã yacc C để tạo opcodes thành mã PHP yacc để tạo AST. Vì vậy, tôi đang xem liệu ai đó đã làm công việc đó chưa.
NikiC

@nikic Một trong những lý do, IMO, chưa ai làm việc này là không có đặc điểm kỹ thuật cho PHP thực sự là gì và cách phân tích cú pháp nó. php-internals trước đây đã bác bỏ hoàn toàn toàn bộ khái niệm này. Do đó, bên ngoài mã nguồn PHP, không có nguồn có thẩm quyền nào để thực hiện phân tích cú pháp. Nếu không có nguồn có thẩm quyền đó để tham khảo, việc xây dựng một trình phân tích cú pháp chính xác sẽ là một cuộc phiêu lưu thực sự. Điều này không may có nghĩa là bắt đầu với dữ liệu yacc hoặc Lemon có thể là lựa chọn tốt nhất.
Charles

@nikic, Charles: Đó là một cuộc phiêu lưu thực sự đối với trình phân tích cú pháp PHP của chúng tôi. Phương pháp tiếp cận: đề xuất từ ​​vựng / ngữ pháp, thử trên hàng nghìn tệp, nhận sai, điều chỉnh, thử lại. Mất khoảng một năm làm việc như vậy để có được một trình phân tích cú pháp mạnh mẽ cho một ngôn ngữ được ghi chép kém. Ít nhất nó đã làm cho chúng tôi. YMMV, nhưng có thể không nhiều.
Ira Baxter

7

Công cụ đo lường PHP Depend chứa mã để tạo AST từ nguồn PHP được viết hoàn toàn bằng PHP. Tuy nhiên, nó sử dụng token_get_all của chính PHP để mã hóa.

Mã nguồn hiện có trên github: https://github.com/manuelpichler/pdepend/tree/master/src/main/php/PHP/Depend

Việc thực hiện AST cho một số phần như biểu thức toán học vẫn chưa hoàn thành lần cuối tôi kiểm tra, nhưng theo tác giả của nó, đó là mục tiêu.


Có AST nhưng không dành cho "phép toán" (tôi đoán ý bạn là "biểu thức"? Đó là một phần quan trọng của ngôn ngữ, đặc biệt là khi bạn xem xét rằng "chuỗi ký tự" được trích dẫn kép (với các biểu thức được nhúng) thực sự rất phức tạp biểu thức chuỗi.
Ira Baxter

2
Bạn đã nhận được tiền thưởng, bởi vì đây là câu trả lời gần nhất cho câu hỏi. Nhưng rõ ràng nó không phải là thực sự có ích, vì nó thiếu, tốt, một nửa số ngữ pháp PHP ...
NikiC

Nội dung của bài đăng này đã lỗi thời. Đã có sự phát triển tích cực kể từ đó, mặc dù tôi không biết nó hỗ trợ ngữ pháp PHP tốt như thế nào.
nhahtdh

4

Chà, điều này không có trong PHP, xin lỗi, nhưng việc xây dựng loại máy móc này rất khó và PHP không đặc biệt thích hợp cho nhiệm vụ xử lý ngôn ngữ.

PHP Front End của chúng tôi cung cấp phân tích cú pháp PHP 4.x và 5.x đầy đủ (EDIT 9/2016: hiện xử lý PHP 7), tự động xây dựng các AST với tất cả các chi tiết của ngữ pháp PHP đầy đủ, có thể tạo văn bản nguồn có thể biên dịch từ AST. Điều này khó hơn những gì bạn có thể nghe được khi bạn xem xét tất cả các chi tiết rắc rối bao gồm các ký tự chuỗi kỳ lạ, các nhận xét được ghi lại, các số với cơ số, v.v.

Nhưng ASTs hầu như không đủ (bạn đã quan sát thấy rằng các mã thông báo thậm chí không đủ).

Nền tảng mà nó được xây dựng, Bộ công cụ tái cấu trúc phần mềm DMS cung cấp hỗ trợ cho việc phân tích và chuyển đổi trọng tài của AST. Nó cũng sẽ đọc các bộ tệp lớn cùng một lúc, cho phép phân tích và chuyển đổi trên các tệp PHP.


1
Cũng giống như một phản hồi cho câu đầu tiên: Đã có các trình tạo phân tích cú pháp, có thể tạo trình phân tích cú pháp từ một máy vẽ yacc (ví dụ: kmyacc). Tức là không có sự khác biệt lớn giữa việc xây dựng nó bằng PHP và xây dựng nó bằng bất kỳ ngôn ngữ nào khác. Tất cả những gì bạn phải làm là "chỉ" (trớ trêu thay) thay thế mã C trong zend_language_parser.y bằng một số mã PHP tạo nên một cây nút.
NikiC

Và liên quan đến phần còn lại: Tôi thực sự muốn có một giải pháp PHP. Nhưng nếu (và điều này có vẻ rất có thể) không có gì như vậy, tôi có thể sẽ sử dụng thứ khác. Tôi đã nghe nói về DMS vài lần ở đây trên SO, tôi sẽ xem xét nó.
NikiC

@ninkic: Tất cả các máy Turing (bao gồm cả PHP) đều có thể mô phỏng tất cả các máy Turing khác, tất nhiên là có thể xây dựng nó bằng PHP. Nhưng a) có chỉ xây dựng trình phân tích cú pháp; Tôi nghĩ trình phân tích cú pháp PHP không được thiết kế để xây dựng một cây mà là để cung cấp cho trình tạo mã p PHP, và tôi nghĩ bạn sẽ thấy nhu cầu là khác nhau, và b) mọi người liên tục mắc sai lầm khi cho rằng nếu họ có AST, mọi thứ khác đều dễ dàng; họ mắc phải sai lầm này phần lớn là vì họ không có kinh nghiệm làm những việc phức tạp với AST. Tôi đã xây dựng DMS vì giả định này là sai.
Ira Baxter

1
a) Có, trình phân tích cú pháp PHP không được thiết kế để xây dựng cây phân tích cú pháp, nó được thiết kế để xây dựng một luồng opcode. Đó là lý do tại sao khó có thể chuyển đổi trình phân tích cú pháp ngôn ngữ zend sang PHP một cách tự động. b) Tôi có lẽ là một trong những người mắc phải sai lầm này;) Từ thực tế là hàng loạt thao tác phức tạp đã có thể được thực hiện với dòng mã thông báo thuần túy, tôi kết luận (trong mắt bạn là nhầm lẫn?) rằng với AST, điều này sẽ dễ dàng hơn và ổn định hơn.
NikiC

@nikic: Bài học từ 50 năm công nghệ trình biên dịch là mỗi biểu diễn chương trình sẽ làm cho một số thứ trở nên dễ dàng. Bạn có thể thực hiện một số thao tác lập trình chỉ trên văn bản. Bạn có thể làm được nhiều việc hơn trên token. Bạn có thể làm được nhiều hơn trên AST. Bạn có thể làm những điều thực sự thú vị nếu bạn có bảng biểu tượng, điều khiển và thông tin luồng dữ liệu (đồ thị), dữ liệu răng cưa biến (phân tích điểm đến). Những gì bạn tìm thấy khi cố gắng tạo mã phức tạp rằng đây là tất cả những thứ thực sự, thực sự hữu ích.
Ira Baxter

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.