Skip to content

Commit

Permalink
capture errors in the token stream
Browse files Browse the repository at this point in the history
  • Loading branch information
gtfierro committed Nov 29, 2023
1 parent 2abe210 commit 8d90a81
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
19 changes: 18 additions & 1 deletion buildingmotif/label_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ class TokenResult:
length: int
error: Optional[str] = None

def __eq__(self, other):
"""
Compare two token results on every
field except for the error field.
"""
if not isinstance(other, TokenResult):
return False
return (
self.value == other.value
and self.token == other.token
and self.length == other.length
)


# null token result
ErrorTokenResult = TokenResult(None, Null(), 0, None)


# type definition for the output of a parser function
@dataclass(frozen=True)
Expand Down Expand Up @@ -189,7 +206,7 @@ def parser(target):
results = []
while True:
part = seq_parser(target)
if not part:
if not part or part[0].value is None:
break
results.extend(part)
# add up the length of all the tokens
Expand Down
24 changes: 20 additions & 4 deletions tests/unit/test_label_parsing.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from typing import List

from buildingmotif.label_parsing import (
COMMON_ABBREVIATIONS,
COMMON_EQUIP_ABBREVIATIONS_BRICK,
Constant,
Delimiter,
ErrorTokenResult,
Identifier,
Null,
TokenResult,
Expand All @@ -23,6 +26,13 @@
from buildingmotif.namespaces import BRICK


def _parse_result_empty(result: List[TokenResult]):
if len(result) == 0:
return True
if len(result) == 1 and result[0].value is None:
return True


def test_ensure_token():
assert ensure_token(Identifier, "abc") == Identifier(
"abc"
Expand All @@ -43,7 +53,9 @@ def test_string_parser():
TokenResult("abc", Identifier("abc"), 3)
], "Should parse the string"
# test that it does not parse the string if it is not at the beginning
assert parser("0abc") == [], "Should not parse the string"
assert parser("0abc") == [
ErrorTokenResult
], f"Should not parse the string {parser('0abc')}"


def test_substring_n_parser():
Expand All @@ -53,7 +65,7 @@ def test_substring_n_parser():
TokenResult("ab", Identifier("ab"), 2)
], "Should parse the string"
# test that it pulls the correct number of characters when there are less than it needs
assert parser("a") == [], "Should not parse the string"
assert parser("a") == [ErrorTokenResult], "Should not parse the string"
# test that it pulls the correct number of characters when there are exactly the number it needs
assert parser("ab") == [
TokenResult("ab", Identifier("ab"), 2)
Expand Down Expand Up @@ -159,7 +171,8 @@ def test_sequence():
TokenResult("1", Identifier("1"), 1),
], "Should parse the string"
assert parser("AHU1-") == [
TokenResult("AHU", Constant(BRICK.Air_Handling_Unit), 3)
TokenResult("AHU", Constant(BRICK.Air_Handling_Unit), 3),
ErrorTokenResult,
], "Should not parse all of the string"


Expand All @@ -176,6 +189,7 @@ def test_many():
assert parser("AHU1") == [
TokenResult("AHU", Constant(BRICK.Air_Handling_Unit), 3),
TokenResult("1", Identifier("1"), 1),
ErrorTokenResult,
]
# no delimiter at the end, so it should not parse the whole thing
assert parser("AHU1/SP2") == [
Expand All @@ -184,6 +198,7 @@ def test_many():
TokenResult("/", Delimiter("/"), 1),
TokenResult("SP", Constant(BRICK.Setpoint), 2),
TokenResult("2", Identifier("2"), 1),
ErrorTokenResult,
]
# test that it parses multiple sequences
assert parser("AHU1/SP2/") == [
Expand Down Expand Up @@ -273,7 +288,8 @@ def test_parse():

result = parse(parser, "AHU1-")
assert result.tokens == [
TokenResult("AHU", Constant(BRICK.Air_Handling_Unit), 3)
TokenResult("AHU", Constant(BRICK.Air_Handling_Unit), 3),
ErrorTokenResult,
], "Should not parse all of the string"
assert not result.success, "Should not parse the string"

Expand Down

0 comments on commit 8d90a81

Please sign in to comment.