Skip to content

Commit

Permalink
Merge pull request #129 from CyberiaResurrection/FallbackParsing
Browse files Browse the repository at this point in the history
Hook up fallback parsing
  • Loading branch information
CyberiaResurrection authored Nov 23, 2024
2 parents ff47316 + 14d5cf0 commit 72d5876
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 21 deletions.
12 changes: 12 additions & 0 deletions PyRoute/Inputs/BaseTransformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,9 +390,21 @@ def trim_raw_string(self, tree):
self.raw = self.raw[index:]

def _square_up_parsed_zero(self, rawstring, parsed):
from PyRoute.Inputs.ParseStarInput import ParseStarInput
bitz = [item for item in rawstring.split(' ') if '' != item]
if 3 == len(bitz) and bitz[0] == parsed['nobles'] and bitz[1] == parsed['base'] and bitz[2] == parsed['zone']:
return parsed
if 2 == len(bitz) and "" == parsed['zone']:
if 2 < len(bitz[0]): # bitz[0] can only possibly be nobles, so return
return parsed
if 1 < len(bitz[1]): # if bitz[1] is more than one char, it can't be a trade zone, so return
return parsed
non_noble = [item for item in bitz[0] if item not in ParseStarInput.valid_nobles]
if 0 < len(non_noble): # If one or more chars in bitz[0] is not a valid noble call, then we have a base code and trade zone
parsed['zone'] = parsed['base']
parsed['base'] = parsed['nobles']
parsed['nobles'] = ''
return parsed
if 3 == len(bitz):
parsed['nobles'] = bitz[0]
parsed['base'] = bitz[1]
Expand Down
65 changes: 54 additions & 11 deletions PyRoute/Inputs/ParseStarInput.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class ParseStarInput:
regex = """
^([0-3]\d[0-4]\d) +
(.{15,}) +
(\w\w\w\w\w\w\w-\w|\?\?\?\?\?\?\?-\?|[\w\?]{7,7}-[\w\?]) +
([A-HXYa-hxy][0-9A-Fa-f]\w\w[0-9A-Fa-f][0-9A-Xa-x][0-9A-Ja-j]-\w|\?\?\?\?\?\?\?-\?|[A-HXYa-hxy\?][0-9A-Fa-f\?][\w\?]{2,2}[0-9A-Fa-f\?][0-9A-Xa-x\?][0-9A-Ja-j\?]-[\w\?]) +
(.{15,}) +
((\{ *[+-]?[0-6] ?\}|-) +(\([0-9A-Za-z]{3}[+-]\d\)|- ) +(\[[0-9A-Za-z]{4}\]|- )|( ) ( ) ( )) +
((\{ *[ +-]?[0-6] ?\}|-) +(\([0-9A-Za-z]{3}[+-]\d\)|- ) +(\[[0-9A-Za-z]{4}\]|- )|( ) ( ) ( )) +
([BcCDeEfFGH]{1,5}|-| ) +
([A-Z]{1,3}|-|\*) +
([ARUFGBarufgb]|-| ) +
Expand All @@ -50,6 +50,8 @@ class ParseStarInput:
station_parser = None
station_transformer = None
deep_space = {}
valid_zone = 'arufgbARUFGB-'
valid_nobles = 'BCcDEeFfGH-'

@staticmethod
def parse_line_into_star_core(star, line, sector, pop_code, ru_calc, fix_pop=False):
Expand Down Expand Up @@ -84,7 +86,7 @@ def parse_line_into_star_core(star, line, sector, pop_code, ru_calc, fix_pop=Fal
if ('' == star.baseCode) or ('-' != star.baseCode and 1 == len(star.baseCode) and not star.baseCode.isalpha()):
star.baseCode = '-'
star.zone = data[13].strip()
if not star.zone or star.zone not in 'arufgbARUFGB-':
if not star.zone or star.zone not in ParseStarInput.valid_zone:
star.zone = '-'
star.zone = star.zone.upper()
star.ggCount = 0 if (len(data[14]) < 3 or not data[14][2] or data[14][2] in 'X?') else int(data[14][2], 16)
Expand Down Expand Up @@ -117,7 +119,10 @@ def parse_line_into_star_core(star, line, sector, pop_code, ru_calc, fix_pop=Fal
star.tradeCode.check_world_codes(star, fix_pop=fix_pop)

if data[5] and data[5].startswith('{'):
imp = int(data[5][1:-1].strip())
raw_imp = data[5][1:-1].strip()
imp = 0
if '' != raw_imp:
imp = int(raw_imp)
star.calculate_importance()
if imp != star.importance:
star.logger.warning(
Expand Down Expand Up @@ -197,11 +202,15 @@ def _unpack_starline(star, line, sector):
else:
result, line = ParseStarInput.parser.parse(line)
except UnexpectedCharacters:
star.logger.error("Unmatched line: {}".format(line))
return None, None
result = ParseStarInput._unpack_starline_fallback(line)
if result is None:
star.logger.error("Unmatched line: {}".format(line))
return None, None
except UnexpectedEOF:
star.logger.error("Unmatched line: {}".format(line))
return None, None
result = ParseStarInput._unpack_starline_fallback(line)
if result is None:
star.logger.error("Unmatched line: {}".format(line))
return None, None
if ParseStarInput.transformer is None:
ParseStarInput.transformer = StarlineTransformer(raw=line)
else:
Expand All @@ -213,13 +222,47 @@ def _unpack_starline(star, line, sector):
ParseStarInput.station_transformer.raw = line
ParseStarInput.station_transformer.crankshaft = False

if is_station:
transformed = ParseStarInput.station_transformer.transform(result)
if not isinstance(result, list):
if is_station:
transformed = ParseStarInput.station_transformer.transform(result)
else:
transformed = ParseStarInput.transformer.transform(result)
else:
transformed = ParseStarInput.transformer.transform(result)
transformed = result

return transformed, is_station

@staticmethod
def _unpack_starline_fallback(line):
matches = ParseStarInput.starline.match(line)
if matches is None:
return
data = list(matches.groups())
parsed = {'position': data[0], 'name': data[1], 'uwp': data[2], 'trade': data[3]}
raw_extensions = data[4].replace(' ', ' ').replace('{ ', '{').replace(' }', '}')
if 2 <= raw_extensions.count(' '):
bitz = raw_extensions.split(' ')
parsed['ix'] = bitz[0]
parsed['ex'] = bitz[1]
parsed['cx'] = bitz[2]
else:
parsed['ix'] = ' ' if data[8] is None else data[8]
parsed['ex'] = ' ' if data[9] is None else data[9]
parsed['cx'] = ' ' if data[10] is None else data[10]
parsed['nobles'] = data[11]
parsed['base'] = data[12]
parsed['zone'] = data[13]
parsed['pbg'] = data[14]
parsed['worlds'] = data[15]
parsed['allegiance'] = data[16]
parsed['residual'] = data[17]

extensions = parsed['ix'] + ' ' + parsed['ex'] + ' ' + parsed['cx']

spacer = ' '
data = [parsed['position'], parsed['name'], parsed['uwp'], parsed['trade'], extensions, parsed['ix'], parsed['ex'], parsed['cx'], spacer, spacer, spacer, parsed['nobles'], parsed['base'], parsed['zone'].upper(), parsed['pbg'], parsed['worlds'], parsed['allegiance'], parsed['residual']]
return data

@staticmethod
def check_tl(star, fullmsg=None):
if '???-' in str(star.uwp) or star.tl_unknown:
Expand Down
4 changes: 2 additions & 2 deletions PyRoute/Inputs/StarlineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StarlineParser:
position: /^([0-3]\d[0-4]\d)/
starname: /(.{15,}) ([\w\?]{7,7}-[\w\?]) /
starname: /(.{15,}) ([A-HXYa-hxy\?][0-9A-Fa-f\?][\w\?]{2,2}[0-9A-Fa-f\?][0-9A-Xa-x\?][0-9A-Ja-j\?]-[\w\?]) /
trade: TRADECODE*
TRADECODE: MINOR_DIEBACK | BINARY | POPCODE | MINOR_SOPHONT | OWNED_COLONY | MAJOR_SOPHONT | RESIDUAL | SINGLETON
Expand All @@ -35,7 +35,7 @@ class StarlineParser:
extensions: ix ex cx | /( ) ( ) ( )/
ix: /\{ *[+-]?[0-6] ?\}|-/
ix: /\{ *[ +-]?[0-6] ?\}|-/
ex: /\([0-9A-Za-z]{3}[+-]\d\)|-/
cx: /(\[[0-9A-Za-z]{4}[\]\}]|-)/
Expand Down
4 changes: 2 additions & 2 deletions PyRoute/Inputs/StarlineStationParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StarlineStationParser:
position: /^([0-3]\d[0-4]\d)/
starname: /(.{15,}) ([\w\?]{7,7}-[\w\?]) /
starname: /(.{15,}) ([A-HXYa-hxy\?][0-9A-Fa-f\?][\w\?]{2,2}[0-9A-Fa-f\?][0-9A-Xa-x\?][0-9A-Ja-j\?]-[\w\?]) /
trade: TRADECODE*
TRADECODE: MINOR_DIEBACK | BINARY | POPCODE | MINOR_SOPHONT | OWNED_COLONY | MAJOR_SOPHONT | RESIDUAL | SINGLETON
Expand All @@ -35,7 +35,7 @@ class StarlineStationParser:
extensions: ix ex cx | /( ) ( ) ( )/
ix: /\{ *[+-]?[0-6] ?\}/
ix: /\{ *[ +-]?[0-6] ?\}/
ex: /\([0-9A-Za-z]{3}[+-]\d\)|-/
cx: /(\[[0-9A-Za-z]{4}[\]\}]|-)/
Expand Down
2 changes: 1 addition & 1 deletion PyRoute/SystemData/UWP.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class UWP(object):
# Port code, size, atmo, hydro, pop, gov, law, the all-important hyphen, then TL
match_string = '^([A-HXYa-hxy\?])([0-9A-Fa-f\?])([0-9A-Za-z\?])([0-9A-Za-z\?])([0-9A-Fa-f\?])([0-9A-Za-z\?])([0-9A-Ja-j\?])-([0-9A-Za-z\?])'
match_string = '^([A-HXYa-hxy\?])([0-9A-Fa-f\?])([0-9A-Za-z\?])([0-9A-Za-z\?])([0-9A-Fa-f\?])([0-9A-Xa-x\?])([0-9A-Ja-j\?])-([0-9A-Za-z\?])'

match = re.compile(match_string)

Expand Down
4 changes: 3 additions & 1 deletion Tests/Hypothesis/Inputs/testHypothesisStarlineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ def comparison_line(draw):
'0000 000000000000000 ???????-? (0 0000000000)A - - A 000 ?0',
'2732 sa0)OkeWHEk4Mmb ???????-? (8PvzPS]UbZypt6 - (8Pv-2) [GZks] f * g 88C E7',
'0000 000000000000000 ???????-? [00000000000]0] - - A 000 ?0',
'0000 000000000000000 ???????-? (00000000000000 - (000-0) [0000] BB - A 000 ?0'
'0000 000000000000000 ???????-? (00000000000000 - (000-0) [0000] BB - A 000 ?0',
'0000 000000000000000 ???????-? (00000000000)0) - - A 000 00?'
]

candidate = draw(from_regex(regex=ParseStarInput.starline, alphabet='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ -{}()[]?\'+*'))
Expand Down Expand Up @@ -320,6 +321,7 @@ class testHypothesisStarlineParser(unittest.TestCase):
@example('0001 000000000000000 ???????-? 000000000000000 - - A 000 --0', False)
@example('0111 -2Z4ig11RbxW010 0000001-1 wJED9E(E(T (HN6 - (113-0) - - - B 114 00y', False)
@example('0000 000000000000000 ???????-? [0000000000]00] - - A 000 ?0', False)
@example('0000 000000000000000 ???????-? (00000000000)0) - - A 000 00?', False)
# Weird parsing cases
@example('0000 000000000000000 ???????-? (00000000000000 - - 0 000 00?)', 'weird')
@example('0000 000000000000000 ???????-? [00000000000000 - - 0 000 00?]', 'weird')
Expand Down
8 changes: 8 additions & 0 deletions Tests/Hypothesis/testStar.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ def setUp(self) -> None:
@example('0101 000000000000000 A0000y0-0 000000000000000 - - 0 000 0000D')
@example('0110 000000000000000 ???????-? 000000000000000 H B A 000 0 00')
@example('0110 000000000000000 ???????-? 000000000000000 e - A 000 00')
@example('0000 000000000000000 0000000-0 0000000000000 B - A A 000 00')
@example('0000 000000000000000 0000000-0 [00000000000000 - - [0000] - - A 000 00')
@example('0110 000000000000000 ???????-? 0000000000 (000 - (000-0) [0000] - - A 000 0 00')
@example('0101 000000000000000 0000000-0 000000000000000 BB A A 000 0 00')
@example('0101 000000000000000 ???????-? 0000000000000 0 0 B - A 000 00')
@example('0101 000000000000000 ???????-? 000000000000000 {-0} (000-0) - * A 000 00')
@example('0101 000000000000000 ???????-? 000000000000000 {-0} (000-0) - - - A 000 00')
@example("0101 000000000000000 ?000000-0 {3 } (7TG-1) [2IBt] EHEG - 569 9 C5'")
def test_parse_line_to_star(self, s):
hyp_line = "Hypothesis input: " + s
sector = Sector('# Core', '# 0, 0')
Expand Down
8 changes: 4 additions & 4 deletions Tests/Inputs/testStarlineParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def test_parser_screwball_synthetic_starline_5(self):
self.assertEqual('', transformed[17], 'Unexpected residual')

def test_parser_screwball_synthetic_starline_6(self):
txt = '0000 000000000000000 0000000-0 000000000000000 - - R 000 000000'
txt = '0000 000000000000000 ?000000-0 000000000000000 - - R 000 000000'

foo = StarlineParser()
result, txt = foo.parse(txt)
Expand All @@ -171,7 +171,7 @@ def test_parser_screwball_synthetic_starline_6(self):
self.assertTrue(isinstance(transformed, list), "Transformed result not list")
self.assertEqual('0000', transformed[0], 'Unexpected hex position')
self.assertEqual('000000000000000', transformed[1], 'Unexpected name')
self.assertEqual('0000000-0', transformed[2], 'Unexpected UWP')
self.assertEqual('?000000-0', transformed[2], 'Unexpected UWP')
self.assertEqual('000000000000000', transformed[3], 'Unexpected trade codes')
self.assertEqual('', transformed[4])
self.assertEqual(None, transformed[5])
Expand Down Expand Up @@ -261,7 +261,7 @@ def test_parser_screwball_synthetic_starline_9(self):
self.assertEqual('', transformed[17], 'Unexpected residual')

def test_parser_screwball_synthetic_starline_10(self):
txt = '0000 000000000000000 0000000-0 000000000000000 - - - 000 00'
txt = '0000 000000000000000 ?000000-0 000000000000000 - - - 000 00'

foo = StarlineParser()
result, txt = foo.parse(txt)
Expand All @@ -271,7 +271,7 @@ def test_parser_screwball_synthetic_starline_10(self):
self.assertTrue(isinstance(transformed, list), "Transformed result not list")
self.assertEqual('0000', transformed[0], 'Unexpected hex position')
self.assertEqual('000000000000000', transformed[1], 'Unexpected name')
self.assertEqual('0000000-0', transformed[2], 'Unexpected UWP')
self.assertEqual('?000000-0', transformed[2], 'Unexpected UWP')
self.assertEqual('000000000000000', transformed[3], 'Unexpected trade codes')
self.assertEqual('', transformed[4])
self.assertEqual(None, transformed[5])
Expand Down

0 comments on commit 72d5876

Please sign in to comment.