Coverage for src/m6rclib/ast_node.py: 85%

37 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-11-11 20:51 +0000

1# Copyright 2024 M6R Ltd. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15""" 

16Types and classes for representing the AST (Abstract Syntax Tree) 

17of a Metaphor document. 

18""" 

19 

20from typing import List, Optional 

21from enum import IntEnum 

22 

23class ASTNodeType(IntEnum): 

24 """ 

25 Types of nodes that can appear in a Metaphor AST. 

26 """ 

27 ROOT: int = 0 

28 TEXT: int = 1 

29 ROLE: int = 2 

30 CONTEXT: int = 3 

31 ACTION: int = 4 

32 

33 

34class ASTNode: 

35 """ 

36 Represents a node in the Abstract Syntax Tree (AST). 

37  

38 Attributes: 

39 node_type (ASTNodeType): The type of the token the node represents. 

40 value (str): The value associated with the node. 

41 """ 

42 def __init__(self, node_type: ASTNodeType, value: str) -> None: 

43 self._node_type: ASTNodeType = node_type 

44 self._value: str = value 

45 self._parent: Optional['ASTNode'] = None 

46 self._children: List['ASTNode'] = [] 

47 

48 def attach_child(self, child: 'ASTNode') -> None: 

49 """Add a child node to this ASTNode.""" 

50 child.parent = self 

51 self._children.append(child) 

52 

53 def detach_child(self, child: 'ASTNode') -> None: 

54 """Detach a child node from this node in the AST.""" 

55 if child not in self.children: 

56 raise ValueError("Node is not a child of this node") 

57 

58 self._children.remove(child) 

59 child.parent = None 

60 

61 @property 

62 def node_type(self) -> ASTNodeType: 

63 """The type of this node.""" 

64 return self._node_type 

65 

66 @property 

67 def value(self) -> str: 

68 """The raw text value of this node.""" 

69 return self._value 

70 

71 @property 

72 def parent(self) -> Optional['ASTNode']: 

73 """The parent node, if any.""" 

74 return self._parent 

75 

76 @parent.setter 

77 def parent(self, new_parent: Optional['ASTNode']) -> None: 

78 self._parent = new_parent 

79 

80 @property 

81 def children(self) -> List['ASTNode']: 

82 """The node's children (returns a copy to prevent modification).""" 

83 return self._children.copy()