def node2json(ast, data): assert (ast['step']['type'] == 'CALL') if ast['step']['data'] == 'Object': return object2json(ast, data) elif ast['step']['data'] == 'Array': return array2json(ast, data) elif ast['step']['data'] == 'String': str = peggy.astdata(ast, data) assert (str[0] == '"' and str[-1] == '"') return str[1:-1].encode('utf-8').decode('unicode_escape') elif ast['step']['data'] == 'Number': num = peggy.astdata(ast, data) try: return int(num) except: return float(num) elif ast['step']['data'] == 'Literal': literal = peggy.astdata(ast, data) if literal == 'true': return True elif literal == 'false': return False elif literal == 'null': return None else: raise RuntimeError('Invalid literal {}'.format(literal)) else: raise RuntimeError('Invalid node type {}'.format(ast['step']['data']))
def grammar2json(ast, data): g = {} assert (ast['step']['type'] == 'CALL' and ast['step']['data'] == 'Grammar') for definition in ast['children']: assert (definition['step']['type'] == 'CALL') assert (definition['step']['data'] == 'Definition') assert (len(definition['children']) == 3) identifier = definition['children'][0] assert ( identifier['step']['type'] == 'CALL' and identifier['step']['data'] == 'Identifier' ) arrow = definition['children'][1] #print(peggy.astdata(identifier,data),peggy.astdata(arrow,data)) assert (arrow['step']['type'] == 'CALL') rule = peggy.astdata(identifier, data).strip().split()[0] g[rule] = { 'type': 'RULE', 'ast': { 'LeftArrow': 'BUILD', 'VoidArrow': 'VOID', 'PruneArrow': 'PRUNE', }[arrow['step']['data']], 'data': node2json(definition['children'][2], data), } return g
def grammar2json(ast, data): g = {} filter_node(ast) assert (ast['step']['type'] == 'CALL' and ast['step']['data'] == 'Grammar') if ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Code': ast['children'].pop(0) for definition in ast['children']: assert (definition['step']['type'] == 'CALL') assert (definition['step']['data'] == 'Definition') identifier = definition['children'][0] assert ( identifier['step']['type'] == 'CALL' and identifier['step']['data'] == 'Identifier' ) definition['children'].pop(0) if definition['children'][0]['step']['type'] == 'CALL' and definition[ 'children'][0]['step']['data'] == 'CaseLiteral': definition['children'].pop(0) assert (len(definition['children']) == 1) rule = peggy.astdata(identifier, data).strip().split()[0] g[rule] = { 'type': 'RULE', 'ast': 'BUILD', 'data': node2json(definition['children'][0], data), } return g
def item2json(ast, data): s = peggy.astdata(ast, data) assert (s) assert (ast['step']['type'] == 'CALL') if ast['step']['data'] == 'Char': if s[0] == '\\': return ord(EscapeChar[s[1:]]) return ord(s) elif ast['step']['data'] == 'Hex': assert (s[0] == '\\' and s[1] == '<' and s[-1] == '>') return ord(bytes.fromhex(s[2:-1]).decode('utf-8')) else: raise RuntimeError('Invalid range item {}'.format(s))
def item2json(ast, data): s = peggy.astdata(ast, data) assert (s) assert (ast['step']['type'] == 'CALL') if ast['step']['data'] == 'Char': if s[0] == '\\': return ord(EscapeChar[s[1:]]) return ord(s) elif ast['step']['data'] == 'Hex': assert (s[0] == '\\' and s[1] == '<' and s[-1] == '>') return ord(bytes.fromhex(s[2:-1]).decode('utf-8')) elif ast['step']['data'] == 'Unicode': assert (len(s) == 6 and s[0] == '\\' and s[1] == 'u') return ord(s.encode('utf-8').decode('unicode_escape')) else: raise RuntimeError('Invalid range item {}'.format(s))
def unit2json(ast, data): unit = {'ast': 'BUILD'} prefix = '' if ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Prefix': prefix = peggy.astdata(ast['children'][0], data) ast['children'].pop(0) if ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Literal': unit['type'] = 'STRING' unit['data'] = peggy.astdata( ast['children'][0], data ).strip()[1:-1].encode('utf-8').decode('unicode_escape') unit['ast'] = 'VOID' elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'CaseLiteral': unit['type'] = 'STRINGI' unit['data'] = peggy.astdata( ast['children'][0], data ).strip()[1:-1].encode('utf-8').decode('unicode_escape') unit['ast'] = 'VOID' elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Identifier': unit['type'] = 'CALL' unit['data'] = peggy.astdata(ast['children'][0], data).strip().split()[0] elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'CharClass': unit['type'] = 'RANGE' unit['data'] = peggy.Range() unit['ast'] = 'VOID' for child in ast['children'][0]['children']: range2json(child, data, unit) elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'WildCard': unit['type'] = 'WILDCARD' unit['ast'] = 'VOID' else: unit = node2json(ast['children'][0], data) if prefix: if prefix == '*': unit['min'] = 0 unit['max'] = sys.maxsize elif prefix == '+': unit['min'] = 1 unit['max'] = sys.maxsize elif prefix == '?': unit['min'] = 0 unit['max'] = 1 elif prefix == '&': unit['predicate'] = True unit['ast'] = 'VOID' elif prefix == '!': unit['predicate'] = False unit['ast'] = 'VOID' elif prefix == ':': unit['ast'] = 'VOID' else: raise NotImplementedError( 'prefix {} not implemented'.format(prefix) ) return unit
def unit2json(ast, data): unit = {'ast': 'BUILD'} prefix = '' suffix = '' if ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Prefix': prefix = peggy.astdata(ast['children'][0], data) ast['children'].pop(0) if ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Literal': unit['type'] = 'STRING' unit['data'] = peggy.astdata( ast['children'][0], data ).strip()[1:-1].encode('utf-8').decode('unicode_escape') unit['ast'] = 'VOID' elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'CaseLiteral': unit['type'] = 'STRING' unit['data'] = peggy.astdata( ast['children'][0], data ).strip()[1:-1].encode('utf-8').decode('unicode_escape') unit['ast'] = 'VOID' elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'Identifier': unit['type'] = 'CALL' unit['data'] = peggy.astdata(ast['children'][0], data).strip().split()[0] elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'CharClass': unit['type'] = 'RANGE' unit['data'] = peggy.Range() unit['ast'] = 'VOID' for child in ast['children'][0]['children']: range2json(child, data, unit) elif ast['children'][0]['step']['type'] == 'CALL' and ast['children'][0][ 'step']['data'] == 'WildCard': unit['type'] = 'WILDCARD' unit['ast'] = 'VOID' else: unit = node2json(ast['children'][0], data) ast['children'].pop(0) if ast['children'] and ast['children'][0]['step'][ 'type'] == 'CALL' and ast['children'][0]['step']['data'] == 'Suffix': suffix = peggy.astdata(ast['children'][0], data) ast['children'].pop(0) if prefix: if prefix == '&': unit['predicate'] = True unit['ast'] = 'VOID' elif prefix == '!': unit['predicate'] = False unit['ast'] = 'VOID' elif prefix == '$': pass else: raise NotImplementedError( 'prefix {} not implemented'.format(prefix) ) if suffix: if suffix == '*': unit['min'] = 0 unit['max'] = sys.maxsize elif suffix == '+': unit['min'] = 1 unit['max'] = sys.maxsize elif suffix == '?': unit['min'] = 0 unit['max'] = 1 elif suffix == 'i': assert (unit['type'] == 'STRING') unit['type'] = 'STRINGI' else: raise NotImplementedError( 'suffix {} not implemented'.format(suffix) ) return unit