Mercurial > python-compiler.rs
diff src/ast_dump.rs @ 13:38b0d63697b1
Import the full AST grammar from CPython 3.5.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 02 Jun 2016 05:33:23 +0100 |
parents | 94ff501bf336 |
children | 719a27f1c1c7 |
line wrap: on
line diff
--- a/src/ast_dump.rs +++ b/src/ast_dump.rs @@ -1,38 +1,116 @@ -use python_ast::{Module, Statement, Expr, BinOp, UnaryOp}; +use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword}; use std::iter; -impl UnaryOp { +impl boolop { + fn to_string(&self) -> &'static str { + match *self { + boolop::And => "and", + boolop::Or => "or" + } + } +} + +impl operator { fn to_string(&self) -> &'static str { match *self { - UnaryOp::UAdd => "+", - UnaryOp::USub => "-", - UnaryOp::Error => "BinOp::Error" + operator::Add => "+", + operator::Sub => "-", + operator::Mult => "*", + operator::MatMult => "@", + operator::Div => "/", + operator::Mod => "%", + operator::Pow => "**", + operator::LShift => "<<", + operator::RShift => ">>", + operator::BitOr => "|", + operator::BitXor => "^", + operator::BitAnd => "&", + operator::FloorDiv => "//", + } + } +} + +impl unaryop { + fn to_string(&self) -> &'static str { + match *self { + unaryop::Invert => "~", + unaryop::Not => "!", + unaryop::UAdd => "+", + unaryop::USub => "-" } } } -impl BinOp { +impl cmpop { fn to_string(&self) -> &'static str { match *self { - BinOp::BinAdd => "+", - BinOp::BinMult => "*", - BinOp::BinEq => "==", - BinOp::BinLt => "<", - BinOp::BinGt => ">", - BinOp::Sub => "-", - BinOp::Div => "/", - BinOp::Error => "BinOp::Error" + cmpop::Eq => "==", + cmpop::NotEq => "!=", + cmpop::Lt => "<", + cmpop::LtE => "<=", + cmpop::Gt => ">", + cmpop::GtE => ">=", + cmpop::Is => "is", + cmpop::IsNot => "is not", + cmpop::In => "in", + cmpop::NotIn => "not in", } } } -impl Expr { +fn args_to_string(args: Vec<expr>) -> String { + let mut arguments = vec!(); + for arg in args { + arguments.push(arg.to_string()); + } + arguments.join(", ") +} + +fn kwargs_to_string(kwargs: Vec<keyword>) -> String { + let mut arguments = vec!(); + for arg in kwargs { + match arg.arg { + Some(arg) => arguments.push(arg), + None => arguments.push("**kwarg".to_string()) + } + } + arguments.join(", ") +} + +fn arguments_to_string(args: arguments) -> String { + let mut arguments = vec!(); + for arg in args.args { + arguments.push(arg.arg); + } + arguments.join(", ") +} + +fn statements_to_string(indent: usize, body: Vec<stmt>) -> String { + let mut statements = vec!(); + for statement in body { + statements.push(statement.to_string(indent + 1)); + } + statements.join("\n") +} + +fn if_else_statements_to_string(indent: usize, body: Vec<stmt>, orelse: Vec<stmt>) -> String { + let body = statements_to_string(indent, body); + if orelse.is_empty() { + body + } else { + format!("{}\n{}else:\n{}", body, make_indent(indent), statements_to_string(indent, orelse)) + } +} + +impl expr { fn to_string(&self) -> String { match self.clone() { - Expr::UnaryOp(op, operand) => format!("{}{}", op.to_string(), operand.to_string()), - Expr::BinOp(a, op, b) => format!("{} {} {}", a.to_string(), op.to_string(), b.to_string()), - Expr::Compare(left, ops, comparators) => format!("{} {}", left.to_string(), { + expr::BoolOp(op, values) => format!("{}({})", op.to_string(), args_to_string(values)), + expr::BinOp(a, op, b) => format!("{} {} {}", a.to_string(), op.to_string(), b.to_string()), + expr::UnaryOp(op, operand) => format!("{}{}", op.to_string(), operand.to_string()), + + expr::Compare(left, ops, comparators) => format!("{} {}", left.to_string(), { let mut arguments = vec!(); // XXX: wrong order! @@ -52,142 +130,60 @@ impl Expr { arguments.join(" ") }), - Expr::Call(func, args) => format!("{}({})", func.to_string(), { - let mut arguments = vec!(); - for arg in args { - arguments.push(arg.to_string()); - } - arguments.join(", ") - }), - Expr::Alias(name, asname) => { - match asname { - None => format!("{}", name), - Some(asname) => format!("{} as {}", name, asname) - } - } - Expr::Attribute(lhs, rhs) => format!("{}.{}", lhs.to_string(), rhs), - Expr::Name(name) => format!("{}", name), - Expr::NameConstant(name) => format!("{}", name), - Expr::Str(s) => format!("\"{}\"", s), - Expr::Num(n) => format!("{}", n), - Expr::List(elts) => format!("[{}]", { - let mut elements = vec!(); - for elt in elts { - elements.push(elt.to_string()); - } - elements.join(", ") - }), - Expr::Error => "Expr::Error".to_string() + expr::Call(func, args, keywords) => format!("{}({}{})", func.to_string(), args_to_string(args), kwargs_to_string(keywords)), + expr::Num(n) => format!("{}", n), + expr::Str(s) => format!("\"{}\"", s), + expr::NameConstant(name) => format!("{}", name), + expr::Attribute(value, attr, ctx) => format!("{}.{}", value.to_string(), attr), + expr::Name(name, ctx) => format!("{}", name), + expr::List(elts, ctx) => format!("[{}]", args_to_string(elts)) } } } +impl arguments { + fn to_string(&self) -> String { + let mut args = vec!(); + for arg in self.args.clone() { + args.push(arg.arg); + } + args.join(", ") + } +} + fn make_indent(indent: usize) -> String { - let indent: String = iter::repeat(" ").take(indent).collect(); - indent + iter::repeat(" ").take(indent).collect() } -impl Statement { +impl stmt { fn to_string(&self, indent: usize) -> String { + let current_indent = make_indent(indent); match self.clone() { - Statement::ClassDef(name, classes, body) => format!("{}def {}({}):\n{}", make_indent(indent), name, { - let mut bases = vec!(); - for class in classes { - bases.push(class.to_string()); - } - bases.join(", ") - }, { - let mut statements = vec!(); - for statement in body { - statements.push(statement.to_string(indent + 1)); - } - statements.join("\n") - }), - Statement::FunctionDef(name, arguments, body) => format!("{}def {}({}):\n{}", make_indent(indent), name, { - let mut args = vec!(); - for arg in arguments { - args.push(arg.to_string()); - } - args.join(", ") - }, { - let mut statements = vec!(); - for statement in body { - statements.push(statement.to_string(indent + 1)); - } - statements.join("\n") + stmt::ClassDef(name, bases, keywords, body, decorator_list) => format!("{}def {}({}):\n{}", current_indent, name, args_to_string(bases), statements_to_string(indent, body)), + stmt::FunctionDef(name, arguments, body, decorator_list, returns) => format!("{}def {}({}):\n{}", current_indent, name, arguments_to_string(arguments), statements_to_string(indent, body)), + stmt::Global(names) => format!("{}global {}", current_indent, names.join(", ")), + stmt::If(test, body, orelse) => format!("{}if {}:\n{}", current_indent, test.to_string(), if_else_statements_to_string(indent, body, orelse)), + stmt::While(test, body, orelse) => format!("{}while {}:\n{}", current_indent, test.to_string(), if_else_statements_to_string(indent, body, orelse)), + stmt::For(target, iter, body, orelse) => format!("{}for {} in {}:\n{}", current_indent, target.to_string(), iter.to_string(), if_else_statements_to_string(indent, body, orelse)), + stmt::Assign(targets, value) => format!("{}{} = {}", current_indent, args_to_string(targets), value.to_string()), + stmt::AugAssign(target, op, value) => format!("{}{} {}= {}", current_indent, target.to_string(), op.to_string(), value.to_string()), + stmt::Return(expr) => format!("{}return{}", current_indent, match expr { + Some(expr) => format!(" {}", expr.to_string()), + None => "".to_string() }), - Statement::Global(names) => format!("{}global {}", make_indent(indent), names.join(", ")), - Statement::If(test, body, orelse) => format!("{}if {}:\n{}", make_indent(indent), test.to_string(), { - let mut statements = vec!(); - for arg in body { - statements.push(arg.to_string(indent + 1)); - } - - let mut orelse_ = vec!(); - for arg in orelse { - orelse_.push(arg.to_string(indent + 1)); - } - - if orelse_.is_empty() { - statements.join("\n") - } else { - format!("{}\n{}else:\n{}", statements.join("\n"), make_indent(indent), orelse_.join("\n")) - } - }), - Statement::While(test, body, orelse) => format!("{}while {}:\n{}", make_indent(indent), test.to_string(), { - let mut statements = vec!(); - for arg in body { - statements.push(arg.to_string(indent + 1)); - } - - let mut orelse_ = vec!(); - for arg in orelse { - orelse_.push(arg.to_string(indent + 1)); - } - - if orelse_.is_empty() { - statements.join("\n") - } else { - format!("{}\n{}else:\n{}", statements.join("\n"), make_indent(indent), orelse_.join("\n")) - } - }), - Statement::For(target, iter, body, orelse) => format!("{}for {} in {}:\n{}", make_indent(indent), target.to_string(), iter.to_string(), { - let mut statements = vec!(); - for arg in body { - statements.push(arg.to_string(indent + 1)); - } - - let mut orelse_ = vec!(); - for arg in orelse { - orelse_.push(arg.to_string(indent + 1)); - } - - if orelse_.is_empty() { - statements.join("\n") - } else { - format!("{}\n{}else:\n{}", statements.join("\n"), make_indent(indent), orelse_.join("\n")) - } - }), - Statement::Assign(targets, value) => format!("{}{} = {}", make_indent(indent), { - let mut exprs = vec!(); - for target in targets { - exprs.push(target.to_string()); - } - exprs.join(", ") - }, value.to_string()), - Statement::AugAssign(target, op, value) => format!("{}{} {}= {}", make_indent(indent), target.to_string(), op.to_string(), value.to_string()), - Statement::Return(expr) => format!("{}return {}", make_indent(indent), expr.to_string()), - Statement::ImportFrom(module, names) => format!("{}from {} import {}", make_indent(indent), module.to_string(), { + stmt::ImportFrom(module, names, level) => format!("{}from {} import {}", current_indent, module.to_string(), { + /* let mut exprs = vec!(); for alias in names.iter() { let alias = alias.to_string(); exprs.push(alias); } exprs.join(", ") + */ + "".to_string() }), - Statement::Expr(expr) => format!("{}{}", make_indent(indent), expr.to_string()), - Statement::Break => format!("{}break", make_indent(indent)), - Statement::Error => format!("{}Statement::Error", make_indent(indent)) + stmt::Expr(expr) => format!("{}{}", current_indent, expr.to_string()), + stmt::Break => format!("{}break", current_indent) } } }