Spaces:
Running
Running
Update parser.py
Browse files
parser.py
CHANGED
@@ -2,9 +2,7 @@
|
|
2 |
import ast
|
3 |
|
4 |
def get_category(node):
|
5 |
-
"""
|
6 |
-
Determine the category of an AST node based on its type.
|
7 |
-
"""
|
8 |
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
9 |
return 'import'
|
10 |
elif isinstance(node, (ast.Assign, ast.AnnAssign, ast.AugAssign)):
|
@@ -20,52 +18,65 @@ def get_category(node):
|
|
20 |
else:
|
21 |
return 'other'
|
22 |
|
23 |
-
def
|
24 |
-
"""
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
list: A list of dictionaries, each containing 'category', 'source', and 'location'.
|
32 |
-
"""
|
33 |
-
with open(file_path, 'r') as file:
|
34 |
-
code = file.read()
|
35 |
|
|
|
|
|
36 |
lines = code.splitlines(keepends=True)
|
37 |
-
|
|
|
|
|
|
|
38 |
|
39 |
parts = []
|
40 |
prev_end = 0
|
41 |
|
42 |
for stmt in tree.body:
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
if start_line > prev_end + 1:
|
47 |
-
spacer_lines = lines[prev_end:start_line - 1]
|
48 |
-
parts.append({
|
49 |
-
'category': 'spacer',
|
50 |
-
'source': ''.join(spacer_lines),
|
51 |
-
'location': (prev_end + 1, start_line - 1)
|
52 |
-
})
|
53 |
-
|
54 |
-
stmt_lines = lines[start_line - 1:end_line]
|
55 |
-
parts.append({
|
56 |
-
'category': get_category(stmt),
|
57 |
-
'source': ''.join(stmt_lines),
|
58 |
-
'location': (start_line, end_line)
|
59 |
-
})
|
60 |
-
|
61 |
-
prev_end = end_line
|
62 |
|
|
|
63 |
if prev_end < len(lines):
|
64 |
remaining_lines = lines[prev_end:]
|
65 |
parts.append({
|
66 |
'category': 'spacer',
|
67 |
'source': ''.join(remaining_lines),
|
68 |
-
'location': (prev_end + 1, len(lines) + 1)
|
|
|
69 |
})
|
70 |
|
71 |
return parts
|
|
|
2 |
import ast
|
3 |
|
4 |
def get_category(node):
|
5 |
+
"""Determine the category of an AST node."""
|
|
|
|
|
6 |
if isinstance(node, (ast.Import, ast.ImportFrom)):
|
7 |
return 'import'
|
8 |
elif isinstance(node, (ast.Assign, ast.AnnAssign, ast.AugAssign)):
|
|
|
18 |
else:
|
19 |
return 'other'
|
20 |
|
21 |
+
def parse_node(node, lines, prev_end, level=0):
|
22 |
+
"""Recursively parse an AST node and its children, assigning hierarchy levels."""
|
23 |
+
parts = []
|
24 |
+
start_line = getattr(node, 'lineno', prev_end + 1)
|
25 |
+
end_line = getattr(node, 'end_lineno', start_line)
|
26 |
+
|
27 |
+
# Handle spacers before the node
|
28 |
+
if start_line > prev_end + 1:
|
29 |
+
spacer_lines = lines[prev_end:start_line - 1]
|
30 |
+
parts.append({
|
31 |
+
'category': 'spacer',
|
32 |
+
'source': ''.join(spacer_lines),
|
33 |
+
'location': (prev_end + 1, start_line - 1),
|
34 |
+
'level': level
|
35 |
+
})
|
36 |
+
|
37 |
+
# Capture the node's source
|
38 |
+
stmt_lines = lines[start_line - 1:end_line]
|
39 |
+
parts.append({
|
40 |
+
'category': get_category(node),
|
41 |
+
'source': ''.join(stmt_lines),
|
42 |
+
'location': (start_line, end_line),
|
43 |
+
'level': level
|
44 |
+
})
|
45 |
|
46 |
+
# Process nested nodes (e.g., class or function bodies)
|
47 |
+
if hasattr(node, 'body'):
|
48 |
+
nested_prev_end = end_line - 1
|
49 |
+
for child in node.body:
|
50 |
+
child_parts = parse_node(child, lines, nested_prev_end, level + 1)
|
51 |
+
parts.extend(child_parts)
|
52 |
+
nested_prev_end = child_parts[-1]['location'][1]
|
53 |
|
54 |
+
return parts
|
|
|
|
|
|
|
|
|
55 |
|
56 |
+
def parse_python_code(code):
|
57 |
+
"""Parse Python code string and return parts with hierarchy."""
|
58 |
lines = code.splitlines(keepends=True)
|
59 |
+
try:
|
60 |
+
tree = ast.parse(code)
|
61 |
+
except SyntaxError:
|
62 |
+
return [{'category': 'error', 'source': 'Invalid Python code', 'location': (1, 1), 'level': 0}]
|
63 |
|
64 |
parts = []
|
65 |
prev_end = 0
|
66 |
|
67 |
for stmt in tree.body:
|
68 |
+
stmt_parts = parse_node(stmt, lines, prev_end)
|
69 |
+
parts.extend(stmt_parts)
|
70 |
+
prev_end = stmt_parts[-1]['location'][1]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
+
# Capture trailing spacers
|
73 |
if prev_end < len(lines):
|
74 |
remaining_lines = lines[prev_end:]
|
75 |
parts.append({
|
76 |
'category': 'spacer',
|
77 |
'source': ''.join(remaining_lines),
|
78 |
+
'location': (prev_end + 1, len(lines) + 1),
|
79 |
+
'level': 0
|
80 |
})
|
81 |
|
82 |
return parts
|