2015-07-16 16 views
8

Tôi đang cố gắng chuyển đổi ant ANTLR3 grammar thành ANTLR4 grammar, để sử dụng nó với thời gian chạy antlr4-python2. Ngữ pháp này là một trình phân tích cú pháp mờ C/C++.Trình phân tích cú pháp ANTLR4 chậm được tạo bằng Python, nhưng nhanh trong Java

Sau khi chuyển đổi nó (về cơ bản loại bỏ các nhà khai thác cây và vị ngữ nghĩa/cú pháp), tôi tạo ra các tập tin python2 sử dụng:

java -jar antlr4.5-complete.jar -Dlanguage=Python2 CPPGrammar.g4

Và mã được tạo ra mà không cần bất kỳ lỗi, vì vậy tôi nhập khẩu nó trong tôi Dự án python (Tôi đang sử dụng PyCharm) để thực hiện một số kiểm tra:

import sys, time 
from antlr4 import * 
from parser.CPPGrammarLexer import CPPGrammarLexer 
from parser.CPPGrammarParser import CPPGrammarParser 

currenttimemillis = lambda: int(round(time.time() * 1000)) 

def is_string(object): 
    return isinstance(object,str) 

def parsecommandstringline(argv): 
    if(2!=len(argv)): 
     raise IndexError("Invalid args size.") 
    if(is_string(argv[1])): 
     return True 
    else: 
     raise TypeError("Argument must be str type.") 

def doparsing(argv): 
    if parsecommandstringline(argv): 
     print("Arguments: OK - {0}".format(argv[1])) 
     input = FileStream(argv[1]) 
     lexer = CPPGrammarLexer(input) 
     stream = CommonTokenStream(lexer) 
     parser = CPPGrammarParser(stream) 
     print("*** Parser: START ***") 
     start = currenttimemillis() 
     tree = parser.code() 
     print("*** Parser: END *** - {0} ms.".format(currenttimemillis()-start)) 
     pass 

def main(argv): 
    tree = doparsing(argv) 
    pass 

if __name__ == '__main__': 
    main(sys.argv) 

Vấn đề là phân tích cú pháp rất chậm. Với một tệp có chứa ~ 200 dòng, phải mất hơn 5 phút để hoàn thành, trong khi phân tích cú pháp của cùng một tệp trong antlrworks chỉ mất 1-2 giây. Phân tích cây antlrworks, tôi nhận thấy rằng expr quy tắc và tất cả các hậu duệ của nó được gọi là rất thường xuyên và tôi nghĩ rằng tôi cần phải đơn giản hóa/thay đổi các quy tắc để thực hiện phân tích cú pháp hoạt động nhanh hơn: expr_tree

là giả định của tôi đúng hoặc tôi đã phạm sai lầm trong khi chuyển đổi ngữ pháp? Những gì có thể được thực hiện để làm cho phân tích nhanh như trên antlrworks?

CẬP NHẬT: Tôi đã xuất ngữ pháp tương tự sang Java và chỉ mất 795ms để hoàn thành việc phân tích cú pháp. Vấn đề có vẻ liên quan nhiều hơn đến việc triển khai python so với ngữ pháp. Có điều gì có thể được thực hiện để tăng tốc phân tích cú pháp Python không?
Tôi đã đọc here rằng python có thể chậm hơn 20-30 lần so với java, nhưng trong trường hợp của tôi python là ~ 400 lần chậm hơn!

+0

Có thời gian thực thi quy tắc hồ sơ để có bất kỳ sự chắc chắn nào. Có thể là việc sử dụng nặng các tập hợp đã phủ định, các chữ trong trình phân tích cú pháp hoặc một thứ khác xuất hiện hoàn toàn lành tính. – GRosenberg

+0

@GRosenberg cảm ơn bạn đã bình luận. Tôi không phải là chuyên gia ANTLR, nhưng dường như tôi không phải là ngữ pháp của tôi và ngữ pháp gốc của tôi có rất nhiều tập hợp hoặc chữ cái phủ định trong trình phân tích cú pháp. Tôi nghĩ rằng đó là một lỗi liên quan đến 'antlr4-python2-runtime' vì nó chỉ mất 1 giây để phân tích cú pháp cùng một tệp trên java.Python có thể chậm hơn, nhưng chậm hơn 400 lần là quá nhiều để nghĩ rằng đó là một vấn đề về phía tôi. – Vektor88

+0

Tuy nhiên, cách tốt nhất để xác định khía cạnh của thời gian chạy không thực hiện là định cấu hình các quy tắc riêng lẻ và xác định khía cạnh quy tắc cụ thể mà quá trình xử lý chậm. Vấn đề là ở phía bạn chỉ theo nghĩa ngữ pháp của bạn đang làm gì đó để kích hoạt chậm lại. Hầu như chắc chắn một sự thay đổi thời gian chạy sẽ được yêu cầu. Phần khó khăn là tìm ra những gì cần sửa chữa. Chìa khóa, may mắn, là một nơi nào đó trong ngữ pháp của bạn. Làm những gì bạn có thể để cô lập nguyên nhân và tạo ra một vấn đề trên repo Antlr Github. Đó là cách nhanh nhất để khắc phục sự cố. – GRosenberg

Trả lời

6

Tôi xác nhận rằng thời gian chạy Python 2 và Python 3 có vấn đề về hiệu suất. Với một vài bản vá, tôi có tốc độ gấp 10 lần trên thời gian chạy python3 (~ 5 giây xuống ~ 400 ms). https://github.com/antlr/antlr4/pull/1010

+2

Yêu cầu kéo đã được chấp nhận: sử dụng thời gian chạy python antlr4 cuối cùng hoặc chờ bản phát hành 4.5.3 trên pypi… – Pinaraf

3

Tôi gặp phải sự cố tương tự vì vậy tôi đã quyết định nhấn vào bài đăng cũ này bằng một giải pháp khả thi. Ngữ pháp của tôi chạy ngay lập tức với TestRig nhưng cực kỳ chậm trên Python 3.

Trong trường hợp của tôi lỗi là mã thông báo không tham lam mà tôi đã sử dụng để tạo ra một dòng chú thích (dấu gạch chéo kép trong C/C++, '%' trong trường hợp của tôi):

TKCOMM : '%' ~[\r\n]* -> skip ; 

này được phần nào hậu thuẫn bằng đường bưu điện này từ sharwell trong cuộc thảo luận này ở đây: https://github.com/antlr/antlr4/issues/658

Khi hiệu suất là một mối quan tâm, tránh sử dụng các nhà khai thác không tham lam, đặc biệt là trong các quy tắc phân tích cú pháp .

Để kiểm tra trường hợp này, bạn có thể muốn xóa các quy tắc/mã thông báo không tham lam khỏi ngữ pháp của mình.

+0

Và bạn đã sử dụng quy tắc nhận xét nào tốt hơn? – DainDwarf

+0

@DainDwarf Ngay bây giờ tôi đang xử lý trước và xóa nhận xét trong một thói quen riêng mà không có ANTLR. Tôi đang sử dụng này như một workaround cho đến khi các bản vá hiệu suất được trích dẫn trên thread này được pip. – Caian

Các vấn đề liên quan