Пример #1
0
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']))
Пример #2
0
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']))
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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))
Пример #6
0
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))
Пример #7
0
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
Пример #8
0
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