parsing - Convert a simple command into an AST in python -
i function in python converts string command ast (abstract syntax tree).
the syntax command follows:
commandname(3, "hello", 5.0, x::int)
a command can accept number of comma separated values can either
- integers
- strings
- floats
- types
suppose function called convert_to_ast
, then
convert_to_ast('commandname(3, "hello", 5.0, x::int)')
should yield following ast:
{ 'type': 'command', 'name': 'commandname', 'args': [{ 'type': 'int', 'value': 3 }, { 'type': 'str', 'value': 'hello' }, { 'type': 'float', 'value': 5.0 }, { 'type': 'var', 'kind': 'int', 'name': 'x }]
seems evaluate string , pick off types there:
>>> items = ast.literal_eval('(404.5, "hello", 5)') >>> [{'type': type(item).__name__, 'value': item} item in items] [{'type': 'float', 'value': 404.5}, {'type': 'str', 'value': 'hello'}, {'type': 'int', 'value': 5}]
of course, if want more interesting things, can access ast directly:
>>> ast.dump(ast.parse('(404.5, "hello", 5)')) "module(body=[expr(value=tuple(elts=[num(n=404.5), str(s='hello'), num(n=5)], ctx=load()))])" >>> ast.parse('(404.5, "hello", 5)').body[0].value.elts [<_ast.num object @ 0x107fa1250>, <_ast.str object @ 0x107fa1290>, <_ast.num object @ 0x107fa12d0>]
for more general thing parsing tuple (as you've added question), still can use python's ast parse (as long syntax is valid python). in case, we'll create ast.nodevisitor
pull out information visits each node of python ast care about. in case, care call
, num
, str
, name
nodes:
import ast class parser(ast.nodevisitor): def __init__(self): self.calls = [] self.current_command = none def visit_call(self, node): name = node.func.id self.current_command = { 'type': 'command', 'name': name, 'args': [] } self.calls.append(self.current_command) arg in node.args: self.visit(arg) self.current_command = none def visit_num(self, node): if not self.current_command: return args = self.current_command['args'] arg = { 'type': type(node.n).__name__, 'value': node.n } args.append(arg) def visit_str(self, node): if not self.current_command: return args = self.current_command['args'] arg = { 'type': 'str', 'value': node.s } args.append(arg) def visit_name(self, node): if not self.current_command: return args = self.current_command['args'] arg = { 'type': 'type', 'kind': node.id } args.append(arg) s = 'commandname(3, "hello", 5.0, int)' tree = ast.parse(s) p = parser() p.visit(tree) print p.calls
Comments
Post a Comment