Hướng dẫn how do you parse in python? - làm thế nào để bạn phân tích cú pháp trong python?

Every programming language does the process of parsing tokens into its meaningful lexical form so that the compiler or interpreter can convert it into its meaningful output. In this article, you will learn about the parsing in Python and what module helps in parsing.

What is Parsing?

Parsing is defined as the process of converting codes to machine language to analyze the correct syntax of the code. Python provides a library called a parser. For example, if an application takes data from the user and the data is not in the required format, in such cases you can use a parser that converts the data into the required format for further processing.

Parsing can be performed in many ways such as using a parser module, parsing through a regular expression, parsing through string methods like the split() and strip() methods.

Let us consider the below code to understand how the parser module helps in parsing.

import parser
print("Input expression for parser module")
expression = "2 + 2"
print(" parsing the input expression")
parsing = parser.expr(expression)
print(parsing)
print(" Converting parsed object to code object")
code = parsing.compile()
print(code)
print(" Parsed result: ")
res = eval(code)
print(res)

Output:

Hướng dẫn how do you parse in python? - làm thế nào để bạn phân tích cú pháp trong python?

Explanation:

First we have imported the parser module that will help us witness the parsing process. Then, we have the print() function to display a output message. The parser.expr() take the Python expression to parse it into object along and will also show the hexadecimal memory location. Another print() function will display the message: Converting parsed object to code object.

On the next line we have used the parsing.compile() method that does the parsing of object expression to code object. The code has the complied output. The parser then churns the object into a module that also takes another memory location. To evaluate the compiled code we have to use the eval() function which we will store in the res object and display it using the print().

Here a string expression is not concatenating but its numbers were working as integers (resulting in 2+2 = 4) because that expression has been parsed in a different approach.

Conclusion:

Software testers and quality assurance team leverages this module to perform different testing. In this article, we have learned how learned how parsing in Python takes place and how Python expression gets converted to data from one format to another.

Although leveraging a separate parsing module does double parsing of a Python program, it will be less efficient. But for testing team, finding the bug or for researchers, creating an interpreter or compiler – this module is very useful.


Mô-đun parser cung cấp một giao diện cho trình phân tích phân tích cú pháp nội bộ và mã byte của Python. Mục đích chính cho giao diện này là cho phép mã Python chỉnh sửa cây phân tích cú pháp của biểu thức Python và tạo mã thực thi từ điều này. Điều này tốt hơn là cố gắng phân tích và sửa đổi một đoạn mã Python tùy ý như một chuỗi vì phân tích cú pháp được thực hiện theo cách giống hệt với mã hình thành ứng dụng. Nó cũng nhanh hơn.

Ghi chú

Từ Python 2.5 trở đi, nó thuận tiện hơn nhiều để cắt ở giai đoạn tạo và biên dịch Cây Syntax Tóm tắt (AST), sử dụng mô -đun ast.

Có một vài điều cần lưu ý về mô -đun này rất quan trọng để sử dụng các cấu trúc dữ liệu được tạo ra. Đây không phải là một hướng dẫn về chỉnh sửa các cây phân tích cho mã Python, nhưng một số ví dụ về việc sử dụng mô -đun parser được trình bày.

Quan trọng nhất, một sự hiểu biết tốt về ngữ pháp Python được xử lý bởi trình phân tích cú pháp nội bộ là bắt buộc. Để biết thông tin đầy đủ về cú pháp ngôn ngữ, hãy tham khảo tham chiếu ngôn ngữ Python. Bản thân trình phân tích cú pháp được tạo từ một đặc tả ngữ pháp được xác định trong tệp Grammar/Grammar trong phân phối Python tiêu chuẩn. Các cây phân tích được lưu trữ trong các đối tượng ST được tạo bởi mô -đun này là đầu ra thực tế từ trình phân tích cú pháp bên trong khi được tạo bởi các hàm expr() hoặc suite(), được mô tả bên dưới. Các đối tượng ST được tạo bởi

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0 mô phỏng một cách trung thực các cấu trúc đó. Xin lưu ý rằng các giá trị của các chuỗi được coi là chính xác, sẽ thay đổi từ một phiên bản Python sang phiên bản khác vì ngữ pháp chính thức cho ngôn ngữ được sửa đổi. Tuy nhiên, việc vận chuyển mã từ phiên bản Python này sang phiên bản khác như văn bản nguồn sẽ luôn cho phép các cây phân tích chính xác được tạo trong phiên bản đích, với hạn chế duy nhất là chuyển sang phiên bản cũ của trình thông dịch sẽ không hỗ trợ các cấu trúc ngôn ngữ gần đây hơn. Các cây phân tích thường không tương thích từ phiên bản này sang phiên bản khác, mặc dù mã nguồn thường tương thích về phía trước trong một loạt phát hành chính.The Python Language Reference. The parser itself is created from a grammar specification defined in the file Grammar/Grammar in the standard Python distribution. The parse trees stored in the ST objects created by this module are the actual output from the internal parser when created by the expr() or suite() functions, described below. The ST objects created by
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0 faithfully simulate those structures. Be aware that the values of the sequences which are considered “correct” will vary from one version of Python to another as the formal grammar for the language is revised. However, transporting code from one Python version to another as source text will always allow correct parse trees to be created in the target version, with the only restriction being that migrating to an older version of the interpreter will not support more recent language constructs. The parse trees are not typically compatible from one version to another, though source code has usually been forward-compatible within a major release series.

Mỗi yếu tố của các chuỗi được trả về bởi

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
1 hoặc
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
2 có một hình thức đơn giản. Trình tự đại diện cho các phần tử không đầu cuối trong ngữ pháp luôn có chiều dài lớn hơn một. Yếu tố đầu tiên là một số nguyên xác định sản xuất trong ngữ pháp. Các số nguyên này được đặt tên biểu tượng trong tệp tiêu đề C
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
3 và mô -đun Python
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
4. Mỗi phần tử bổ sung của chuỗi đại diện cho một thành phần của sản xuất như được công nhận trong chuỗi đầu vào: Đây luôn là các chuỗi có cùng dạng với cha mẹ. Một khía cạnh quan trọng của cấu trúc này cần lưu ý là các từ khóa được sử dụng để xác định loại nút cha, chẳng hạn như từ khóa
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
5 trong
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
6, được đưa vào cây nút mà không có bất kỳ xử lý đặc biệt nào. Ví dụ: từ khóa
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
5 được biểu thị bằng Tuple
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
8, trong đó
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
9 là giá trị số được liên kết với tất cả các mã thông báo
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
0, bao gồm các tên biến và chức năng được xác định bởi người dùng. Trong một biểu mẫu thay thế được trả về khi yêu cầu thông tin số dòng, cùng một mã thông báo có thể được biểu diễn dưới dạng
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
1, trong đó
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
2 đại diện cho số dòng tại đó biểu tượng thiết bị đầu cuối được tìm thấy.

Các phần tử đầu cuối được thể hiện theo nhiều cách tương tự, nhưng không có bất kỳ phần tử con nào và việc bổ sung văn bản nguồn được xác định. Ví dụ về từ khóa

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
5 ở trên là đại diện. Các loại ký hiệu thiết bị đầu cuối khác nhau được xác định trong tệp tiêu đề C
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
4 và mô -đun Python
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
5.

Các đối tượng ST không bắt buộc phải hỗ trợ chức năng của mô -đun này, nhưng được cung cấp cho ba mục đích: cho phép một ứng dụng khấu hao chi phí xử lý các cây phân tích phức tạp, để cung cấp biểu diễn cây phân tích để bảo tồn không gian bộ nhớ khi so sánh với Python Liệt kê hoặc đại diện tuple, và để dễ dàng tạo ra các mô -đun bổ sung trong C thao tác cây phân tích. Một lớp trình bao bọc đơn giản có thể được tạo ra trong Python để che giấu việc sử dụng các đối tượng ST.

Mô -đun parser xác định các chức năng cho một vài mục đích riêng biệt. Mục đích quan trọng nhất là tạo các đối tượng ST và chuyển đổi các đối tượng ST sang các biểu diễn khác như cây phân tích và các đối tượng mã được biên dịch, nhưng cũng có các hàm phục vụ để truy vấn loại cây phân tích được biểu thị bởi một đối tượng ST.

Xem thêm

Mô -đun
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
4

Các hằng số hữu ích đại diện cho các nút bên trong của cây phân tích.

Mô -đun
>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
5

Các hằng số hữu ích đại diện cho các nút lá của cây phân tích và các chức năng để kiểm tra các giá trị nút.

Tạo đối tượng ST

Các đối tượng ST có thể được tạo từ mã nguồn hoặc từ cây phân tích. Khi tạo một đối tượng ST từ nguồn, các chức năng khác nhau được sử dụng để tạo các biểu mẫu

>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
9 và
import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()
0.

________ 31 ________ 32 (Nguồn) ¶(source)

Hàm expr() phân tích nguồn tham số như thể nó là đầu vào cho

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()
4. Nếu phân tích cú pháp thành công, một đối tượng ST được tạo để giữ biểu diễn cây phân tích bên trong, nếu không một ngoại lệ thích hợp được nâng lên.

________ 31 ________ 36 (Nguồn)(source)

Hàm suite() phân tích nguồn tham số như thể nó là đầu vào cho

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()
8. Nếu phân tích cú pháp thành công, một đối tượng ST được tạo để giữ biểu diễn cây phân tích bên trong, nếu không một ngoại lệ thích hợp được nâng lên.

________ 31 ________ 40 (trình tự)(sequence)

Hàm này chấp nhận một cây phân tích được biểu diễn dưới dạng một chuỗi và xây dựng một biểu diễn bên trong nếu có thể. Nếu nó có thể xác nhận rằng cây phù hợp với ngữ pháp Python và tất cả các nút là các loại nút hợp lệ trong phiên bản máy chủ của Python, một đối tượng ST được tạo từ biểu diễn bên trong và được trả lại cho cuộc gọi. Nếu có một vấn đề tạo ra biểu diễn nội bộ hoặc nếu cây không thể được xác thực, ngoại lệ parser1 sẽ được nâng lên. Một đối tượng ST được tạo ra theo cách này không nên được giả định để biên dịch chính xác; Các trường hợp ngoại lệ bình thường được tăng lên bằng cách biên dịch vẫn có thể được bắt đầu khi đối tượng ST được truyền đến parser2. Điều này có thể chỉ ra các vấn đề không liên quan đến cú pháp (chẳng hạn như ngoại lệ parser3), nhưng cũng có thể là do các cấu trúc như kết quả của phân tích cú pháp parser4, thoát khỏi trình phân tích cú pháp Python nhưng được kiểm tra bởi trình biên dịch byte.

Các chuỗi đại diện cho các mã thông báo đầu cuối có thể được biểu diễn dưới dạng danh sách hai phần tử của Mẫu parser5 hoặc là danh sách ba phần tử của Mẫu parser6. Nếu phần tử thứ ba có mặt, nó được coi là số dòng hợp lệ. Số dòng có thể được chỉ định cho bất kỳ tập hợp con của các ký hiệu đầu cuối trong cây đầu vào.

________ 31 ________ 48 (trình tự) ¶(sequence)

Đây là chức năng tương tự như

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0. Điểm vào này được duy trì để tương thích ngược.

Chuyển đổi đối tượng ST

Các đối tượng ST, bất kể đầu vào được sử dụng để tạo chúng, có thể được chuyển đổi thành các cây phân tích được biểu diễn dưới dạng danh sách hoặc các cây, hoặc có thể được biên dịch thành các đối tượng mã thực thi. Cây phân tích có thể được trích xuất có hoặc không có thông tin đánh số dòng.

________ 31 ________ 51 (ST, line_info = false, col_info = false) ¶(st, line_info=False, col_info=False)

Hàm này chấp nhận một đối tượng ST từ người gọi trong ST và trả về danh sách Python đại diện cho cây phân tích tương đương. Biểu diễn danh sách kết quả có thể được sử dụng để kiểm tra hoặc tạo ra một cây phân tích mới ở dạng danh sách. Hàm này không thất bại miễn là bộ nhớ có sẵn để xây dựng biểu diễn danh sách. Nếu cây Parse sẽ chỉ được sử dụng để kiểm tra,

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
2 nên được sử dụng thay vào đó để giảm mức tiêu thụ và phân mảnh bộ nhớ. Khi yêu cầu biểu diễn danh sách, hàm này nhanh hơn đáng kể so với truy xuất biểu diễn tuple và chuyển đổi nó thành danh sách lồng nhau.

Nếu line_info là đúng, thông tin số dòng sẽ được bao gồm cho tất cả các mã thông báo thiết bị đầu cuối dưới dạng phần tử thứ ba của danh sách đại diện cho mã thông báo. Lưu ý rằng số dòng cung cấp chỉ định dòng mà mã thông báo kết thúc. Thông tin này bị bỏ qua nếu cờ là sai hoặc bỏ qua.

________ 31 ________ 54 (ST, line_info = false, col_info = false) ¶(st, line_info=False, col_info=False)

Hàm này chấp nhận một đối tượng ST từ người gọi trong ST và trả về một tuple python đại diện cho cây phân tích tương đương. Khác với việc trả lại một tuple thay vì một danh sách, chức năng này giống hệt với

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
1.

Nếu line_info là đúng, thông tin số dòng sẽ được bao gồm cho tất cả các mã thông báo thiết bị đầu cuối dưới dạng phần tử thứ ba của danh sách đại diện cho mã thông báo. Thông tin này bị bỏ qua nếu cờ là sai hoặc bỏ qua.

________ 31 ________ 57 (st, filename = '')(st, filename='')

Trình biên dịch Byte Python có thể được gọi trên một đối tượng ST để tạo các đối tượng mã có thể được sử dụng như một phần của các chức năng ast8 hoặc ast9 tích hợp. Hàm này cung cấp giao diện cho trình biên dịch, chuyển cây phân tích bên trong từ ST đến trình phân tích cú pháp, sử dụng tên tệp nguồn được chỉ định bởi tham số FileName. Giá trị mặc định được cung cấp cho tên tệp chỉ ra rằng nguồn là một đối tượng ST.

Biên dịch một đối tượng ST có thể dẫn đến các ngoại lệ liên quan đến biên dịch; Một ví dụ sẽ là một parser0 do cây phân tích gây ra cho parser4: Tuyên bố này được coi là hợp pháp trong ngữ pháp chính thức cho Python nhưng không phải là một cấu trúc ngôn ngữ pháp lý. parser0 được nâng lên cho điều kiện này thực sự được tạo ra bởi trình biên dịch byte Python thông thường, đó là lý do tại sao nó có thể được nâng lên tại thời điểm này bởi mô-đun parser. Hầu hết các nguyên nhân gây ra lỗi biên dịch có thể được chẩn đoán theo chương trình bằng cách kiểm tra cây phân tích.

Truy vấn trên các đối tượng ST

Hai chức năng được cung cấp cho phép một ứng dụng xác định xem ST có được tạo dưới dạng biểu thức hay bộ. Cả hai chức năng này đều có thể được sử dụng để xác định xem ST có được tạo từ mã nguồn thông qua expr() hoặc suite() hay từ cây phân tích thông qua

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0.

________ 31 ________ 68 (ST)(st)

Khi ST đại diện cho biểu mẫu

>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10
9, hàm này trả về Grammar/Grammar0, nếu không nó sẽ trả về Grammar/Grammar1. Điều này rất hữu ích, vì các đối tượng mã thường không thể được truy vấn cho thông tin này bằng các hàm tích hợp hiện có. Lưu ý rằng các đối tượng mã được tạo bởi parser2 cũng không thể được truy vấn như thế này và giống hệt với các đối tượng được tạo bởi hàm Grammar/Grammar3 tích hợp.

________ 31 ________ 75 (ST)(st)

Hàm này phản ánh Grammar/Grammar6 ở chỗ nó báo cáo liệu một đối tượng ST có đại diện cho một hình thức

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()
0 hay không, thường được gọi là một bộ của bộ. Không an toàn khi cho rằng chức năng này tương đương với Grammar/Grammar8, vì các đoạn cú pháp bổ sung có thể được hỗ trợ trong tương lai.

Ngoại lệ và xử lý lỗi

Mô-đun phân tích cú pháp xác định một ngoại lệ duy nhất, nhưng cũng có thể vượt qua các trường hợp ngoại lệ tích hợp khác từ các phần khác của môi trường thời gian chạy Python. Xem từng chức năng để biết thông tin về các ngoại lệ mà nó có thể nêu ra.

Ngoại lệ ________ 31 ________ 80¶

Ngoại lệ được nâng lên khi xảy ra lỗi trong mô -đun phân tích cú pháp. Điều này thường được sản xuất cho các lỗi xác nhận thay vì parser0 được nâng lên trong quá trình phân tích cú pháp bình thường. Đối số ngoại lệ là một chuỗi mô tả lý do của sự thất bại hoặc một tuple chứa một chuỗi gây ra sự thất bại từ cây phân tích được chuyển đến

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0 và một chuỗi giải thích. Các cuộc gọi đến
>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0 Cần có khả năng xử lý một trong hai loại ngoại lệ, trong khi các cuộc gọi đến các chức năng khác trong mô -đun sẽ chỉ cần nhận thức được các giá trị chuỗi đơn giản.

Lưu ý rằng các chức năng parser2, expr()suite() có thể nêu ra các ngoại lệ thường được nêu ra bởi quá trình phân tích cú pháp và biên dịch. Chúng bao gồm các trường hợp ngoại lệ được xây dựng parser3, expr()8, parser0 và suite()0. Trong những trường hợp này, những ngoại lệ này mang tất cả các ý nghĩa thường được liên kết với chúng. Tham khảo các mô tả của từng chức năng để biết thông tin chi tiết.

Đối tượng ST

So sánh được đặt hàng và bình đẳng được hỗ trợ giữa các đối tượng ST. Pickling của các đối tượng ST (sử dụng mô -đun suite()1) cũng được hỗ trợ.

________ 31 ________ 93¶

Loại đối tượng được trả về bởi expr(), suite()

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
0.

Các đối tượng ST có các phương thức sau:

________ 97 ________ 98 (fileName = '')(filename='')

Giống như suite()9.

________ 97 ________ 68 ()()

Giống như

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
02.

________ 97 ________ 75 ()()

Giống như

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
05.

________ 97 ________ 107 (line_info = false, col_info = false) ¶(line_info=False, col_info=False)

Giống như

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
08.

________ 97 ________ 110 (line_info = false, col_info = false) ¶(line_info=False, col_info=False)

Giống như

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10
11.

Ví dụ: Mô phỏng của ________ 73¶

Mặc dù nhiều hoạt động hữu ích có thể diễn ra giữa tạo phân tích cú pháp và mã byte, hoạt động đơn giản nhất là không làm gì cả. Đối với mục đích này, sử dụng mô -đun parser để tạo cấu trúc dữ liệu trung gian tương đương với mã

>>> code = compile('a + 5', 'file.py', 'eval')
>>> a = 5
>>> eval(code)
10

Hoạt động tương đương bằng cách sử dụng mô -đun parser có phần dài hơn và cho phép cây phân tích phân tích bên trong trung gian được giữ lại như một đối tượng ST:

>>> import parser
>>> st = parser.expr('a + 5')
>>> code = st.compile('file.py')
>>> a = 5
>>> eval(code)
10

Một ứng dụng cần cả đối tượng ST và mã có thể đóng gói mã này thành các chức năng có sẵn:

import parser

def load_suite(source_string):
    st = parser.suite(source_string)
    return st, st.compile()

def load_expression(source_string):
    st = parser.expr(source_string)
    return st, st.compile()

Làm thế nào để phân tích cú pháp hoạt động trong Python?

Trong Python, có một mô-đun tích hợp có tên Parse cung cấp giao diện giữa trình phân tích cú pháp và trình biên dịch bên trong Python, trong đó mô-đun này cho phép chương trình Python chỉnh sửa các đoạn mã nhỏ và tạo chương trình thực thi từ cây parse được chỉnh sửa này của Pythonmã số.

Phân tích tập tin trong Python là gì?

Phân tích tệp và phân tích dữ liệu trong Python Phần I (Phân tích tương tác và trực quan hóa dữ liệu) 1) Định nghĩa phân tích tệp: phân tích về cơ bản có nghĩa là '' giải quyết (một câu) vào các phần thành phần của nó và mô tả vai trò cú pháp của chúng ''.Trong điện toán, phân tích cú pháp là 'một hành động phân tích cú pháp một chuỗi hoặc một văn bản'.resolve (a sentence) into its component parts and describe their syntactic roles''. In computing, parsing is 'an act of parsing a string or a text'.