Skip to content

Commit fef2ec8

Browse files
authored
Merge pull request #2 from CEDARScript/fixes2
Small fixes
2 parents 74b960d + 82e36d0 commit fef2ec8

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ AI-assisted development tools to understand and execute these tasks.
1717
## Features
1818

1919
- Parse `CEDARScript` Abstract Syntax Tree (`AST`) that was generated by Tree-Sitter into a list of commands
20-
- Support for various code manipulation andn analysis commands (CREATE, UPDATE, RM, MV, SELECT)
20+
- Support for various code manipulation and analysis commands (CREATE, UPDATE, RM, MV, SELECT)
2121
- Return results in `XML` format for easier parsing and processing by LLM systems
2222

2323
## Installation

src/cedarscript_ast_parser/__init__.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
__version__ = "0.2.0"
1+
__version__ = "0.2.1"
22

33
from .cedarscript_ast_parser import (
44
CEDARScriptASTParser, ParseError, Command,
55
CreateCommand, RmFileCommand, MvFileCommand, UpdateCommand,
6-
SelectCommand, IdentifierFromFile, SingleFileClause, Segment, Marker, BodyOrWhole, MarkerType, RelativeMarker, RelativePositionType,
7-
MoveClause, DeleteClause, InsertClause, ReplaceClause, EditingAction, Region, BodyOrWhole, WhereClause, RegionClause
6+
SelectCommand, IdentifierFromFile, SingleFileClause, Segment, Marker, BodyOrWhole, MarkerType, RelativeMarker,
7+
RelativePositionType, MoveClause, DeleteClause, InsertClause, ReplaceClause, EditingAction, Region, BodyOrWhole,
8+
WhereClause, RegionClause
89
)
910

1011
__all__ = (
1112
CEDARScriptASTParser, ParseError, Command,
1213
CreateCommand, RmFileCommand, MvFileCommand, UpdateCommand,
13-
SelectCommand, IdentifierFromFile, SingleFileClause, Segment, Marker, BodyOrWhole, MarkerType, RelativeMarker, RelativePositionType,
14-
MoveClause, DeleteClause, InsertClause, ReplaceClause, EditingAction, Region, BodyOrWhole, WhereClause, RegionClause
14+
SelectCommand, IdentifierFromFile, SingleFileClause, Segment, Marker, BodyOrWhole, MarkerType, RelativeMarker,
15+
RelativePositionType, MoveClause, DeleteClause, InsertClause, ReplaceClause, EditingAction, Region, BodyOrWhole,
16+
WhereClause, RegionClause
1517
)
1618

1719

src/cedarscript_ast_parser/cedarscript_ast_parser.py

+25-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import cedarscript_grammar
77
from dataclasses import dataclass
88

9+
910
class ParseError(NamedTuple):
1011
command_ordinal: int
1112
message: str
@@ -14,10 +15,13 @@ class ParseError(NamedTuple):
1415
suggestion: str
1516

1617
def __str__(self):
18+
line_msg = f'; LINE #{self.line}' if self.line else ''
19+
col_msg = f'; COLUMN #{self.column}' if self.column else ''
20+
suggestion_msg = f'{self.suggestion} ' if self.suggestion else ''
1721
return (
18-
f"<error-details><error-location>COMMAND #{self.command_ordinal}{f'; LINE #{self.line}' if self.line else ''}{f'; COLUMN #{self.column}' if self.column else ''}</error-location>"
22+
f"<error-details><error-location>COMMAND #{self.command_ordinal}{line_msg}{col_msg}</error-location>"
1923
f"<type>PARSING (no commands were applied at all)</type><description>{self.message}</description>"
20-
f"<suggestion>{f"{self.suggestion} " if self.suggestion else ""}"
24+
f"<suggestion>{suggestion_msg}"
2125
"(NEVER apologize; just take a deep breath, re-read grammar rules (enclosed by <grammar.js> tags) "
2226
"and fix you CEDARScript syntax)</suggestion></error-details>"
2327
)
@@ -39,6 +43,7 @@ class MarkerCompatible:
3943
def as_marker(self) -> 'Marker':
4044
pass
4145

46+
4247
@dataclass
4348
class Marker(MarkerCompatible):
4449
type: MarkerType
@@ -69,7 +74,7 @@ def __str__(self):
6974
case RelativePositionType.AT:
7075
pass
7176
case _:
72-
result = f'{result} ({self.qualifier.replace('_', ' ')})'
77+
result = f'{result} ({str(self.qualifier).replace('_', ' ')})'
7378
return result
7479

7580

@@ -112,7 +117,7 @@ def as_marker(self) -> Marker:
112117
return Marker(self.identifier_type, self.where_clause.value, self.offset)
113118

114119
def __str__(self):
115-
result = f"{self.identifier_type.lower()} ({self.where_clause})"
120+
result = f"{str(self.identifier_type).lower()} ({self.where_clause})"
116121
if self.offset is not None:
117122
result += f" at offset {self.offset}"
118123
return f"{result} from file {self.file_path}"
@@ -188,6 +193,7 @@ def files_to_change(self) -> tuple[str, ...]:
188193
class CreateCommand(FileCommand):
189194
content: str
190195

196+
191197
@dataclass
192198
class RmFileCommand(FileCommand):
193199
pass
@@ -423,8 +429,10 @@ def parse_where_clause(self, node):
423429
return WhereClause(field=field, operator=operator, value=value)
424430

425431
def parse_update_action(self, node):
426-
child_types = ['update_delete_region_clause', 'update_delete_mos_clause', 'update_move_region_clause', 'update_move_mos_clause',
427-
'insert_clause', 'replace_mos_clause', 'replace_region_clause']
432+
child_types = [
433+
'update_delete_region_clause', 'update_delete_mos_clause', 'update_move_region_clause',
434+
'update_move_mos_clause', 'insert_clause', 'replace_mos_clause', 'replace_region_clause'
435+
]
428436
action_node = self.find_first_by_type(node.named_children, child_types)
429437
if action_node is None:
430438
raise ValueError("No valid action found in update command")
@@ -525,7 +533,7 @@ def parse_offset_clause(self, node):
525533
return None
526534
return int(self.find_first_by_type(node.children, 'number').text)
527535

528-
def parse_relative_indentation(self, node) -> int:
536+
def parse_relative_indentation(self, node) -> int | None:
529537
node = self.find_first_by_type(node.named_children, 'relative_indentation')
530538
if node is None:
531539
return None
@@ -537,13 +545,12 @@ def parse_content(self, node) -> str | tuple[Region, int | None]:
537545
return None
538546
match content.type:
539547
case 'content_clause':
540-
return self.parse_content_clause(content) # str
548+
return self.parse_content_clause(content) # str
541549
case 'content_from_segment':
542-
return self.parse_content_from_segment_clause(content) # tuple[Region, int]
550+
return self.parse_content_from_segment_clause(content) # tuple[Region, int]
543551
case _:
544552
raise ValueError(f"Invalid content type: {content.type}")
545553

546-
547554
def parse_singlefile_clause(self, node):
548555
if node is None or node.type != 'singlefile_clause':
549556
raise ValueError("Expected singlefile_clause node")
@@ -581,7 +588,8 @@ def parse_to_value_clause(self, node):
581588
raise ValueError("No value found in to_value_clause")
582589
return self.parse_string(value_node)
583590

584-
def parse_string(self, node):
591+
@staticmethod
592+
def parse_string(node):
585593
match node.type.casefold():
586594
case 'string':
587595
node = node.named_children[0]
@@ -596,7 +604,8 @@ def parse_string(self, node):
596604

597605
return text
598606

599-
def parse_multiline_string(self, node):
607+
@staticmethod
608+
def parse_multiline_string(node):
600609
return node.text.decode('utf8').strip("'''").strip('"""')
601610

602611
def parse_relative_indent_block(self, node) -> str:
@@ -610,7 +619,8 @@ def parse_relative_indent_block(self, node) -> str:
610619
lines.append(f"{' ' * (4 * indent)}{content.text}")
611620
return '\n'.join(lines)
612621

613-
def find_first_by_type(self, nodes: Sequence[any], child_type):
622+
@staticmethod
623+
def find_first_by_type(nodes: Sequence[any], child_type):
614624
if isinstance(child_type, list):
615625
for child in nodes:
616626
if child.type in child_type:
@@ -621,7 +631,8 @@ def find_first_by_type(self, nodes: Sequence[any], child_type):
621631
return child
622632
return None
623633

624-
def find_first_by_field_name(self, node: any, field_names):
634+
@staticmethod
635+
def find_first_by_field_name(node: any, field_names):
625636
if not isinstance(field_names, list):
626637
return node.child_by_field_name(field_names)
627638

0 commit comments

Comments
 (0)