Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hook up fallback parsing #129

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading