diff --git a/pydevicetree/ast/reference.py b/pydevicetree/ast/reference.py index 8a683e7..8168d87 100644 --- a/pydevicetree/ast/reference.py +++ b/pydevicetree/ast/reference.py @@ -33,16 +33,13 @@ def to_dts(self) -> str: class Path: """A Path uniquely identifies a Node by its parents and (optionally) unit address""" - def __init__(self, path: str, address: Optional[int] = None): + def __init__(self, path: str): """Create a path out of a string""" - self.path = list(filter(lambda s: s != '', path.split('/'))) - self.address = address + self.path = path def to_dts(self) -> str: """Format the Path in Devicetree Source format""" - if self.address: - return '/%s@%x' % ('/'.join(self.path), self.address) - return '/' + '/'.join(self.path) + return self.path def __repr__(self) -> str: return "" @@ -51,19 +48,15 @@ def __eq__(self, other: object) -> bool: if isinstance(other, Path): return self.to_dts() == other.to_dts() if isinstance(other, str): - if ("@" not in other) and (self.address is not None): - return self.to_dts().split("@")[0] == other return self.to_dts() == other return False def __iter__(self) -> Iterator[str]: - return iter(['/'] + self.path) + return iter(self.path.split("/")) def replace(self, old: str, new: str) -> 'Path': """Replace any elements of the path which match 'old' with a new element 'new'""" - path = [e.replace(old, new) for e in self.path] - return Path('/' + '/'.join(path), self.address) - + return Path(self.path.replace(old, new)) class Reference: """A Reference is a Devicetree construct which points to a Node in the tree diff --git a/pydevicetree/source/grammar.py b/pydevicetree/source/grammar.py index 19cc59e..38a48ee 100644 --- a/pydevicetree/source/grammar.py +++ b/pydevicetree/source/grammar.py @@ -9,14 +9,14 @@ node_name = p.Word(p.alphanums + ",.-+_") ^ p.Literal("/") integer = p.pyparsing_common.integer ^ (p.Literal("0x").suppress() + p.pyparsing_common.hex_integer) unit_address = p.pyparsing_common.hex_integer +node_handle = node_name("node_name") + p.Optional(p.Literal("@") + unit_address("address")) property_name = p.Word(p.alphanums + ",.-_+?#") label = p.Word(p.alphanums + "_").setResultsName("label") label_creation = p.Combine(label + p.Literal(":")) string = p.QuotedString(quoteChar='"') stringlist = p.delimitedList(string) node_path = p.Combine(p.Literal("/") + \ - p.delimitedList(node_name, delim="/", combine=True)).setResultsName("path") + \ - p.Optional(p.Literal("@").suppress() + unit_address("address")) + p.delimitedList(node_handle, delim="/", combine=True)).setResultsName("path") path_reference = p.Literal("&{").suppress() + node_path + p.Literal("}").suppress() label_reference = p.Literal("&").suppress() + label reference = path_reference ^ label_reference @@ -43,8 +43,7 @@ property_assignment = property_name("property_name") + p.Optional(p.Literal("=").suppress() + \ (property_values)).setResultsName("value") + p.Literal(";").suppress() -node_opener = p.Optional(label_creation) + node_name("node_name") + \ - p.Optional(p.Literal("@").suppress() + unit_address("address")) + p.Literal("{").suppress() +node_opener = p.Optional(label_creation) + node_handle + p.Literal("{").suppress() node_reference_opener = reference + p.Literal("{").suppress() node_closer = p.Literal("}").suppress() + p.Literal(";").suppress() node_definition = p.Forward() diff --git a/pydevicetree/source/parser.py b/pydevicetree/source/parser.py index 5d70dd5..158e2c0 100644 --- a/pydevicetree/source/parser.py +++ b/pydevicetree/source/parser.py @@ -77,9 +77,14 @@ def transformLabel(string, location, tokens): def transformPath(string, location, tokens): """Transforms a ParseResult into a Path""" - if tokens.address: - return Path(tokens.path, tokens.address) - return Path(tokens.path) + path = "" + for handle in tokens.path[0].split("/"): + if "@" in handle: + node, address = handle.split("@") + path += "/%s@%x" % (node, int(address)) + elif handle != "": + path += "/" + handle + return Path(path) def transformPathReference(string, location, tokens): """Transforms a ParseResult into a PathReference""" diff --git a/tests/test_grammar.py b/tests/test_grammar.py index 93889af..213f0f6 100644 --- a/tests/test_grammar.py +++ b/tests/test_grammar.py @@ -14,11 +14,13 @@ def test_label(self): def test_node_path(self): from pydevicetree.ast import Path self.assertEqual(node_path.parseString("/path/to/foo@deadbeef")[0], Path("/path/to/foo@deadbeef")) + self.assertEqual(node_path.parseString("/path/to@0/foo@deadbeef")[0], Path("/path/to@0/foo@deadbeef")) def test_reference(self): from pydevicetree.ast import Label, Path self.assertEqual(reference.parseString("&mylabel")[0].label, Label("mylabel")) self.assertEqual(reference.parseString("&{/path/to/foo@deadbeef}")[0].path, Path("/path/to/foo@deadbeef")) + self.assertEqual(reference.parseString("&{/path/to@0/foo@deadbeef}")[0].path, Path("/path/to@0/foo@deadbeef")) def test_arith_expr(self): self.assertEqual(arith_expr.parseString("(1 + 2)").asList(), [3])