nac3parser: add comment support #68
|
@ -10,43 +10,45 @@ module Python
|
||||||
|
|
||||||
stmt = FunctionDef(identifier name, arguments args,
|
stmt = FunctionDef(identifier name, arguments args,
|
||||||
stmt* body, expr* decorator_list, expr? returns,
|
stmt* body, expr* decorator_list, expr? returns,
|
||||||
string? type_comment)
|
string? type_comment, identifier* config_comment)
|
||||||
| AsyncFunctionDef(identifier name, arguments args,
|
| AsyncFunctionDef(identifier name, arguments args,
|
||||||
stmt* body, expr* decorator_list, expr? returns,
|
stmt* body, expr* decorator_list, expr? returns,
|
||||||
string? type_comment)
|
string? type_comment, identifier* config_comment)
|
||||||
|
|
||||||
| ClassDef(identifier name,
|
| ClassDef(identifier name,
|
||||||
expr* bases,
|
expr* bases,
|
||||||
keyword* keywords,
|
keyword* keywords,
|
||||||
stmt* body,
|
stmt* body,
|
||||||
expr* decorator_list)
|
expr* decorator_list, identifier* config_comment)
|
||||||
| Return(expr? value)
|
| Return(expr? value, identifier* config_comment)
|
||||||
|
|
||||||
| Delete(expr* targets)
|
| Delete(expr* targets, identifier* config_comment)
|
||||||
| Assign(expr* targets, expr value, string? type_comment)
|
| Assign(expr* targets, expr value, string? type_comment, identifier* config_comment)
|
||||||
| AugAssign(expr target, operator op, expr value)
|
| AugAssign(expr target, operator op, expr value, identifier* config_comment)
|
||||||
-- 'simple' indicates that we annotate simple name without parens
|
-- 'simple' indicates that we annotate simple name without parens
|
||||||
| AnnAssign(expr target, expr annotation, expr? value, bool simple)
|
| AnnAssign(expr target, expr annotation, expr? value, bool simple, identifier* config_comment)
|
||||||
|
|
||||||
-- use 'orelse' because else is a keyword in target languages
|
-- use 'orelse' because else is a keyword in target languages
|
||||||
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
|
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment, identifier* config_comment)
|
||||||
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
|
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment, identifier* config_comment)
|
||||||
| While(expr test, stmt* body, stmt* orelse)
|
| While(expr test, stmt* body, stmt* orelse, identifier* config_comment)
|
||||||
| If(expr test, stmt* body, stmt* orelse)
|
| If(expr test, stmt* body, stmt* orelse, identifier* config_comment)
|
||||||
| With(withitem* items, stmt* body, string? type_comment)
|
| With(withitem* items, stmt* body, string? type_comment, identifier* config_comment)
|
||||||
| AsyncWith(withitem* items, stmt* body, string? type_comment)
|
| AsyncWith(withitem* items, stmt* body, string? type_comment, identifier* config_comment)
|
||||||
|
|
||||||
| Raise(expr? exc, expr? cause)
|
| Raise(expr? exc, expr? cause, identifier* config_comment)
|
||||||
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
|
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody, identifier* config_comment)
|
||||||
| Assert(expr test, expr? msg)
|
| Assert(expr test, expr? msg, identifier* config_comment)
|
||||||
|
|
||||||
| Import(alias* names)
|
| Import(alias* names, identifier* config_comment)
|
||||||
| ImportFrom(identifier? module, alias* names, int level)
|
| ImportFrom(identifier? module, alias* names, int level, identifier* config_comment)
|
||||||
|
|
||||||
| Global(identifier* names)
|
| Global(identifier* names, identifier* config_comment)
|
||||||
| Nonlocal(identifier* names)
|
| Nonlocal(identifier* names, identifier* config_comment)
|
||||||
| Expr(expr value)
|
| Expr(expr value, identifier* config_comment)
|
||||||
| Pass | Break | Continue
|
| Pass(identifier* config_comment)
|
||||||
|
| Break(identifier* config_comment)
|
||||||
|
| Continue(identifier* config_comment)
|
||||||
|
|
||||||
-- col_offset is the byte offset in the utf8 string the parser uses
|
-- col_offset is the byte offset in the utf8 string the parser uses
|
||||||
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
||||||
|
|
|
@ -72,7 +72,7 @@ pub fn get_str_from_ref<'a>(lock: &'a MutexGuard<Interner>, id: StrRef) -> &'a s
|
||||||
lock.resolve(id.0).unwrap()
|
lock.resolve(id.0).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
type Ident = StrRef;
|
pub type Ident = StrRef;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Located<T, U = ()> {
|
pub struct Located<T, U = ()> {
|
||||||
|
@ -114,6 +114,7 @@ pub enum StmtKind<U = ()> {
|
||||||
decorator_list: Vec<Expr<U>>,
|
decorator_list: Vec<Expr<U>>,
|
||||||
returns: Option<Box<Expr<U>>>,
|
returns: Option<Box<Expr<U>>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
AsyncFunctionDef {
|
AsyncFunctionDef {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
@ -122,6 +123,7 @@ pub enum StmtKind<U = ()> {
|
||||||
decorator_list: Vec<Expr<U>>,
|
decorator_list: Vec<Expr<U>>,
|
||||||
returns: Option<Box<Expr<U>>>,
|
returns: Option<Box<Expr<U>>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
ClassDef {
|
ClassDef {
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
@ -129,28 +131,34 @@ pub enum StmtKind<U = ()> {
|
||||||
keywords: Vec<Keyword<U>>,
|
keywords: Vec<Keyword<U>>,
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
decorator_list: Vec<Expr<U>>,
|
decorator_list: Vec<Expr<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Return {
|
Return {
|
||||||
value: Option<Box<Expr<U>>>,
|
value: Option<Box<Expr<U>>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Delete {
|
Delete {
|
||||||
targets: Vec<Expr<U>>,
|
targets: Vec<Expr<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Assign {
|
Assign {
|
||||||
targets: Vec<Expr<U>>,
|
targets: Vec<Expr<U>>,
|
||||||
value: Box<Expr<U>>,
|
value: Box<Expr<U>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
AugAssign {
|
AugAssign {
|
||||||
target: Box<Expr<U>>,
|
target: Box<Expr<U>>,
|
||||||
op: Operator,
|
op: Operator,
|
||||||
value: Box<Expr<U>>,
|
value: Box<Expr<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
AnnAssign {
|
AnnAssign {
|
||||||
target: Box<Expr<U>>,
|
target: Box<Expr<U>>,
|
||||||
annotation: Box<Expr<U>>,
|
annotation: Box<Expr<U>>,
|
||||||
value: Option<Box<Expr<U>>>,
|
value: Option<Box<Expr<U>>>,
|
||||||
simple: bool,
|
simple: bool,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
For {
|
For {
|
||||||
target: Box<Expr<U>>,
|
target: Box<Expr<U>>,
|
||||||
|
@ -158,6 +166,7 @@ pub enum StmtKind<U = ()> {
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
orelse: Vec<Stmt<U>>,
|
orelse: Vec<Stmt<U>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
AsyncFor {
|
AsyncFor {
|
||||||
target: Box<Expr<U>>,
|
target: Box<Expr<U>>,
|
||||||
|
@ -165,61 +174,80 @@ pub enum StmtKind<U = ()> {
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
orelse: Vec<Stmt<U>>,
|
orelse: Vec<Stmt<U>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
While {
|
While {
|
||||||
test: Box<Expr<U>>,
|
test: Box<Expr<U>>,
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
orelse: Vec<Stmt<U>>,
|
orelse: Vec<Stmt<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
If {
|
If {
|
||||||
test: Box<Expr<U>>,
|
test: Box<Expr<U>>,
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
orelse: Vec<Stmt<U>>,
|
orelse: Vec<Stmt<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
With {
|
With {
|
||||||
items: Vec<Withitem<U>>,
|
items: Vec<Withitem<U>>,
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
AsyncWith {
|
AsyncWith {
|
||||||
items: Vec<Withitem<U>>,
|
items: Vec<Withitem<U>>,
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
type_comment: Option<String>,
|
type_comment: Option<String>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Raise {
|
Raise {
|
||||||
exc: Option<Box<Expr<U>>>,
|
exc: Option<Box<Expr<U>>>,
|
||||||
cause: Option<Box<Expr<U>>>,
|
cause: Option<Box<Expr<U>>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Try {
|
Try {
|
||||||
body: Vec<Stmt<U>>,
|
body: Vec<Stmt<U>>,
|
||||||
handlers: Vec<Excepthandler<U>>,
|
handlers: Vec<Excepthandler<U>>,
|
||||||
orelse: Vec<Stmt<U>>,
|
orelse: Vec<Stmt<U>>,
|
||||||
finalbody: Vec<Stmt<U>>,
|
finalbody: Vec<Stmt<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Assert {
|
Assert {
|
||||||
test: Box<Expr<U>>,
|
test: Box<Expr<U>>,
|
||||||
msg: Option<Box<Expr<U>>>,
|
msg: Option<Box<Expr<U>>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Import {
|
Import {
|
||||||
names: Vec<Alias>,
|
names: Vec<Alias>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
ImportFrom {
|
ImportFrom {
|
||||||
module: Option<Ident>,
|
module: Option<Ident>,
|
||||||
names: Vec<Alias>,
|
names: Vec<Alias>,
|
||||||
level: usize,
|
level: usize,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Global {
|
Global {
|
||||||
names: Vec<Ident>,
|
names: Vec<Ident>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Nonlocal {
|
Nonlocal {
|
||||||
names: Vec<Ident>,
|
names: Vec<Ident>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Expr {
|
Expr {
|
||||||
value: Box<Expr<U>>,
|
value: Box<Expr<U>>,
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
|
},
|
||||||
|
Pass {
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
|
},
|
||||||
|
Break {
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
|
},
|
||||||
|
Continue {
|
||||||
|
config_comment: Vec<Ident>,
|
||||||
},
|
},
|
||||||
Pass,
|
|
||||||
Break,
|
|
||||||
Continue,
|
|
||||||
}
|
}
|
||||||
pub type Stmt<U = ()> = Located<StmtKind<U>, U>;
|
pub type Stmt<U = ()> = Located<StmtKind<U>, U>;
|
||||||
|
|
||||||
|
@ -558,7 +586,7 @@ pub mod fold {
|
||||||
pub fn fold_stmt<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: Stmt<U>) -> Result<Stmt<F::TargetU>, F::Error> {
|
pub fn fold_stmt<U, F: Fold<U> + ?Sized>(#[allow(unused)] folder: &mut F, node: Stmt<U>) -> Result<Stmt<F::TargetU>, F::Error> {
|
||||||
fold_located(folder, node, |folder, node| {
|
fold_located(folder, node, |folder, node| {
|
||||||
match node {
|
match node {
|
||||||
StmtKind::FunctionDef { name,args,body,decorator_list,returns,type_comment } => {
|
StmtKind::FunctionDef { name,args,body,decorator_list,returns,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::FunctionDef {
|
Ok(StmtKind::FunctionDef {
|
||||||
name: Foldable::fold(name, folder)?,
|
name: Foldable::fold(name, folder)?,
|
||||||
args: Foldable::fold(args, folder)?,
|
args: Foldable::fold(args, folder)?,
|
||||||
|
@ -566,9 +594,10 @@ pub mod fold {
|
||||||
decorator_list: Foldable::fold(decorator_list, folder)?,
|
decorator_list: Foldable::fold(decorator_list, folder)?,
|
||||||
returns: Foldable::fold(returns, folder)?,
|
returns: Foldable::fold(returns, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::AsyncFunctionDef { name,args,body,decorator_list,returns,type_comment } => {
|
StmtKind::AsyncFunctionDef { name,args,body,decorator_list,returns,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::AsyncFunctionDef {
|
Ok(StmtKind::AsyncFunctionDef {
|
||||||
name: Foldable::fold(name, folder)?,
|
name: Foldable::fold(name, folder)?,
|
||||||
args: Foldable::fold(args, folder)?,
|
args: Foldable::fold(args, folder)?,
|
||||||
|
@ -576,152 +605,176 @@ pub mod fold {
|
||||||
decorator_list: Foldable::fold(decorator_list, folder)?,
|
decorator_list: Foldable::fold(decorator_list, folder)?,
|
||||||
returns: Foldable::fold(returns, folder)?,
|
returns: Foldable::fold(returns, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::ClassDef { name,bases,keywords,body,decorator_list } => {
|
StmtKind::ClassDef { name,bases,keywords,body,decorator_list,config_comment } => {
|
||||||
Ok(StmtKind::ClassDef {
|
Ok(StmtKind::ClassDef {
|
||||||
name: Foldable::fold(name, folder)?,
|
name: Foldable::fold(name, folder)?,
|
||||||
bases: Foldable::fold(bases, folder)?,
|
bases: Foldable::fold(bases, folder)?,
|
||||||
keywords: Foldable::fold(keywords, folder)?,
|
keywords: Foldable::fold(keywords, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
decorator_list: Foldable::fold(decorator_list, folder)?,
|
decorator_list: Foldable::fold(decorator_list, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Return { value } => {
|
StmtKind::Return { value,config_comment } => {
|
||||||
Ok(StmtKind::Return {
|
Ok(StmtKind::Return {
|
||||||
value: Foldable::fold(value, folder)?,
|
value: Foldable::fold(value, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Delete { targets } => {
|
StmtKind::Delete { targets,config_comment } => {
|
||||||
Ok(StmtKind::Delete {
|
Ok(StmtKind::Delete {
|
||||||
targets: Foldable::fold(targets, folder)?,
|
targets: Foldable::fold(targets, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Assign { targets,value,type_comment } => {
|
StmtKind::Assign { targets,value,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::Assign {
|
Ok(StmtKind::Assign {
|
||||||
targets: Foldable::fold(targets, folder)?,
|
targets: Foldable::fold(targets, folder)?,
|
||||||
value: Foldable::fold(value, folder)?,
|
value: Foldable::fold(value, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::AugAssign { target,op,value } => {
|
StmtKind::AugAssign { target,op,value,config_comment } => {
|
||||||
Ok(StmtKind::AugAssign {
|
Ok(StmtKind::AugAssign {
|
||||||
target: Foldable::fold(target, folder)?,
|
target: Foldable::fold(target, folder)?,
|
||||||
op: Foldable::fold(op, folder)?,
|
op: Foldable::fold(op, folder)?,
|
||||||
value: Foldable::fold(value, folder)?,
|
value: Foldable::fold(value, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::AnnAssign { target,annotation,value,simple } => {
|
StmtKind::AnnAssign { target,annotation,value,simple,config_comment } => {
|
||||||
Ok(StmtKind::AnnAssign {
|
Ok(StmtKind::AnnAssign {
|
||||||
target: Foldable::fold(target, folder)?,
|
target: Foldable::fold(target, folder)?,
|
||||||
annotation: Foldable::fold(annotation, folder)?,
|
annotation: Foldable::fold(annotation, folder)?,
|
||||||
value: Foldable::fold(value, folder)?,
|
value: Foldable::fold(value, folder)?,
|
||||||
simple: Foldable::fold(simple, folder)?,
|
simple: Foldable::fold(simple, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::For { target,iter,body,orelse,type_comment } => {
|
StmtKind::For { target,iter,body,orelse,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::For {
|
Ok(StmtKind::For {
|
||||||
target: Foldable::fold(target, folder)?,
|
target: Foldable::fold(target, folder)?,
|
||||||
iter: Foldable::fold(iter, folder)?,
|
iter: Foldable::fold(iter, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
orelse: Foldable::fold(orelse, folder)?,
|
orelse: Foldable::fold(orelse, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::AsyncFor { target,iter,body,orelse,type_comment } => {
|
StmtKind::AsyncFor { target,iter,body,orelse,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::AsyncFor {
|
Ok(StmtKind::AsyncFor {
|
||||||
target: Foldable::fold(target, folder)?,
|
target: Foldable::fold(target, folder)?,
|
||||||
iter: Foldable::fold(iter, folder)?,
|
iter: Foldable::fold(iter, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
orelse: Foldable::fold(orelse, folder)?,
|
orelse: Foldable::fold(orelse, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::While { test,body,orelse } => {
|
StmtKind::While { test,body,orelse,config_comment } => {
|
||||||
Ok(StmtKind::While {
|
Ok(StmtKind::While {
|
||||||
test: Foldable::fold(test, folder)?,
|
test: Foldable::fold(test, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
orelse: Foldable::fold(orelse, folder)?,
|
orelse: Foldable::fold(orelse, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::If { test,body,orelse } => {
|
StmtKind::If { test,body,orelse,config_comment } => {
|
||||||
Ok(StmtKind::If {
|
Ok(StmtKind::If {
|
||||||
test: Foldable::fold(test, folder)?,
|
test: Foldable::fold(test, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
orelse: Foldable::fold(orelse, folder)?,
|
orelse: Foldable::fold(orelse, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::With { items,body,type_comment } => {
|
StmtKind::With { items,body,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::With {
|
Ok(StmtKind::With {
|
||||||
items: Foldable::fold(items, folder)?,
|
items: Foldable::fold(items, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::AsyncWith { items,body,type_comment } => {
|
StmtKind::AsyncWith { items,body,type_comment,config_comment } => {
|
||||||
Ok(StmtKind::AsyncWith {
|
Ok(StmtKind::AsyncWith {
|
||||||
items: Foldable::fold(items, folder)?,
|
items: Foldable::fold(items, folder)?,
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
type_comment: Foldable::fold(type_comment, folder)?,
|
type_comment: Foldable::fold(type_comment, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Raise { exc,cause } => {
|
StmtKind::Raise { exc,cause,config_comment } => {
|
||||||
Ok(StmtKind::Raise {
|
Ok(StmtKind::Raise {
|
||||||
exc: Foldable::fold(exc, folder)?,
|
exc: Foldable::fold(exc, folder)?,
|
||||||
cause: Foldable::fold(cause, folder)?,
|
cause: Foldable::fold(cause, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Try { body,handlers,orelse,finalbody } => {
|
StmtKind::Try { body,handlers,orelse,finalbody,config_comment } => {
|
||||||
Ok(StmtKind::Try {
|
Ok(StmtKind::Try {
|
||||||
body: Foldable::fold(body, folder)?,
|
body: Foldable::fold(body, folder)?,
|
||||||
handlers: Foldable::fold(handlers, folder)?,
|
handlers: Foldable::fold(handlers, folder)?,
|
||||||
orelse: Foldable::fold(orelse, folder)?,
|
orelse: Foldable::fold(orelse, folder)?,
|
||||||
finalbody: Foldable::fold(finalbody, folder)?,
|
finalbody: Foldable::fold(finalbody, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Assert { test,msg } => {
|
StmtKind::Assert { test,msg,config_comment } => {
|
||||||
Ok(StmtKind::Assert {
|
Ok(StmtKind::Assert {
|
||||||
test: Foldable::fold(test, folder)?,
|
test: Foldable::fold(test, folder)?,
|
||||||
msg: Foldable::fold(msg, folder)?,
|
msg: Foldable::fold(msg, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Import { names } => {
|
StmtKind::Import { names,config_comment } => {
|
||||||
Ok(StmtKind::Import {
|
Ok(StmtKind::Import {
|
||||||
names: Foldable::fold(names, folder)?,
|
names: Foldable::fold(names, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::ImportFrom { module,names,level } => {
|
StmtKind::ImportFrom { module,names,level,config_comment } => {
|
||||||
Ok(StmtKind::ImportFrom {
|
Ok(StmtKind::ImportFrom {
|
||||||
module: Foldable::fold(module, folder)?,
|
module: Foldable::fold(module, folder)?,
|
||||||
names: Foldable::fold(names, folder)?,
|
names: Foldable::fold(names, folder)?,
|
||||||
level: Foldable::fold(level, folder)?,
|
level: Foldable::fold(level, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Global { names } => {
|
StmtKind::Global { names,config_comment } => {
|
||||||
Ok(StmtKind::Global {
|
Ok(StmtKind::Global {
|
||||||
names: Foldable::fold(names, folder)?,
|
names: Foldable::fold(names, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Nonlocal { names } => {
|
StmtKind::Nonlocal { names,config_comment } => {
|
||||||
Ok(StmtKind::Nonlocal {
|
Ok(StmtKind::Nonlocal {
|
||||||
names: Foldable::fold(names, folder)?,
|
names: Foldable::fold(names, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Expr { value } => {
|
StmtKind::Expr { value,config_comment } => {
|
||||||
Ok(StmtKind::Expr {
|
Ok(StmtKind::Expr {
|
||||||
value: Foldable::fold(value, folder)?,
|
value: Foldable::fold(value, folder)?,
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Pass { } => {
|
StmtKind::Pass { config_comment } => {
|
||||||
Ok(StmtKind::Pass {
|
Ok(StmtKind::Pass {
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Break { } => {
|
StmtKind::Break { config_comment } => {
|
||||||
Ok(StmtKind::Break {
|
Ok(StmtKind::Break {
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
StmtKind::Continue { } => {
|
StmtKind::Continue { config_comment } => {
|
||||||
Ok(StmtKind::Continue {
|
Ok(StmtKind::Continue {
|
||||||
|
config_comment: Foldable::fold(config_comment, folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) {
|
) {
|
||||||
if let StmtKind::While { test, body, orelse } = &stmt.node {
|
if let StmtKind::While { test, body, orelse, .. } = &stmt.node {
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
||||||
|
@ -228,7 +228,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let StmtKind::If { test, body, orelse } = &stmt.node {
|
if let StmtKind::If { test, body, orelse, .. } = &stmt.node {
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
||||||
|
@ -306,11 +306,11 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
stmt: &Stmt<Option<Type>>,
|
stmt: &Stmt<Option<Type>>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match &stmt.node {
|
match &stmt.node {
|
||||||
StmtKind::Pass => {}
|
StmtKind::Pass { .. } => {}
|
||||||
StmtKind::Expr { value } => {
|
StmtKind::Expr { value, .. } => {
|
||||||
generator.gen_expr(ctx, value);
|
generator.gen_expr(ctx, value);
|
||||||
}
|
}
|
||||||
StmtKind::Return { value } => {
|
StmtKind::Return { value, .. } => {
|
||||||
let value = value.as_ref().map(|v| generator.gen_expr(ctx, v).unwrap());
|
let value = value.as_ref().map(|v| generator.gen_expr(ctx, v).unwrap());
|
||||||
let value = value.as_ref().map(|v| v as &dyn BasicValue);
|
let value = value.as_ref().map(|v| v as &dyn BasicValue);
|
||||||
ctx.builder.build_return(value);
|
ctx.builder.build_return(value);
|
||||||
|
@ -328,11 +328,11 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>(
|
||||||
generator.gen_assign(ctx, target, value);
|
generator.gen_assign(ctx, target, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StmtKind::Continue => {
|
StmtKind::Continue { .. } => {
|
||||||
ctx.builder.build_unconditional_branch(ctx.loop_bb.unwrap().0);
|
ctx.builder.build_unconditional_branch(ctx.loop_bb.unwrap().0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
StmtKind::Break => {
|
StmtKind::Break { .. }=> {
|
||||||
ctx.builder.build_unconditional_branch(ctx.loop_bb.unwrap().1);
|
ctx.builder.build_unconditional_branch(ctx.loop_bb.unwrap().1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1439,8 +1439,8 @@ impl TopLevelComposer {
|
||||||
return Err("unsupported statement type in class definition body".into());
|
return Err("unsupported statement type in class definition body".into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::StmtKind::Pass => {}
|
ast::StmtKind::Pass { .. } => {}
|
||||||
ast::StmtKind::Expr { value: _ } => {} // typically a docstring; ignoring all expressions matches CPython behavior
|
ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior
|
||||||
_ => return Err("unsupported statement type in class definition body".into()),
|
_ => return Err("unsupported statement type in class definition body".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,7 +330,7 @@ impl TopLevelComposer {
|
||||||
ast::StmtKind::With { body, .. } => {
|
ast::StmtKind::With { body, .. } => {
|
||||||
result.extend(Self::get_all_assigned_field(body.as_slice())?);
|
result.extend(Self::get_all_assigned_field(body.as_slice())?);
|
||||||
}
|
}
|
||||||
ast::StmtKind::Pass => {}
|
ast::StmtKind::Pass { .. } => {}
|
||||||
ast::StmtKind::Assert { .. } => {}
|
ast::StmtKind::Assert { .. } => {}
|
||||||
ast::StmtKind::Expr { .. } => {}
|
ast::StmtKind::Expr { .. } => {}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ impl<'a> Inferencer<'a> {
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
StmtKind::If { test, body, orelse } => {
|
StmtKind::If { test, body, orelse, .. } => {
|
||||||
self.check_expr(test, defined_identifiers)?;
|
self.check_expr(test, defined_identifiers)?;
|
||||||
self.should_have_value(test)?;
|
self.should_have_value(test)?;
|
||||||
let mut body_identifiers = defined_identifiers.clone();
|
let mut body_identifiers = defined_identifiers.clone();
|
||||||
|
@ -211,7 +211,7 @@ impl<'a> Inferencer<'a> {
|
||||||
}
|
}
|
||||||
Ok(body_returned && orelse_returned)
|
Ok(body_returned && orelse_returned)
|
||||||
}
|
}
|
||||||
StmtKind::While { test, body, orelse } => {
|
StmtKind::While { test, body, orelse, .. } => {
|
||||||
self.check_expr(test, defined_identifiers)?;
|
self.check_expr(test, defined_identifiers)?;
|
||||||
self.should_have_value(test)?;
|
self.should_have_value(test)?;
|
||||||
let mut defined_identifiers = defined_identifiers.clone();
|
let mut defined_identifiers = defined_identifiers.clone();
|
||||||
|
@ -230,7 +230,7 @@ impl<'a> Inferencer<'a> {
|
||||||
self.check_block(body, &mut new_defined_identifiers)?;
|
self.check_block(body, &mut new_defined_identifiers)?;
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
StmtKind::Expr { value } => {
|
StmtKind::Expr { value, .. } => {
|
||||||
self.check_expr(value, defined_identifiers)?;
|
self.check_expr(value, defined_identifiers)?;
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ impl<'a> Inferencer<'a> {
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
StmtKind::Return { value } => {
|
StmtKind::Return { value, .. } => {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
self.check_expr(value, defined_identifiers)?;
|
self.check_expr(value, defined_identifiers)?;
|
||||||
self.should_have_value(value)?;
|
self.should_have_value(value)?;
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
fn fold_stmt(&mut self, node: ast::Stmt<()>) -> Result<ast::Stmt<Self::TargetU>, Self::Error> {
|
fn fold_stmt(&mut self, node: ast::Stmt<()>) -> Result<ast::Stmt<Self::TargetU>, Self::Error> {
|
||||||
let stmt = match node.node {
|
let stmt = match node.node {
|
||||||
// we don't want fold over type annotation
|
// we don't want fold over type annotation
|
||||||
ast::StmtKind::AnnAssign { target, annotation, value, simple } => {
|
ast::StmtKind::AnnAssign { target, annotation, value, simple, config_comment } => {
|
||||||
self.infer_pattern(&target)?;
|
self.infer_pattern(&target)?;
|
||||||
let target = Box::new(self.fold_expr(*target)?);
|
let target = Box::new(self.fold_expr(*target)?);
|
||||||
let value = if let Some(v) = value {
|
let value = if let Some(v) = value {
|
||||||
|
@ -105,14 +105,14 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
Located {
|
Located {
|
||||||
location: node.location,
|
location: node.location,
|
||||||
custom: None,
|
custom: None,
|
||||||
node: ast::StmtKind::AnnAssign { target, annotation, value, simple },
|
node: ast::StmtKind::AnnAssign { target, annotation, value, simple, config_comment },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::StmtKind::For { ref target, .. } => {
|
ast::StmtKind::For { ref target, .. } => {
|
||||||
self.infer_pattern(target)?;
|
self.infer_pattern(target)?;
|
||||||
fold::fold_stmt(self, node)?
|
fold::fold_stmt(self, node)?
|
||||||
}
|
}
|
||||||
ast::StmtKind::Assign { ref targets, .. } => {
|
ast::StmtKind::Assign { ref targets, ref config_comment, .. } => {
|
||||||
if targets.iter().all(|t| matches!(t.node, ast::ExprKind::Name { .. })) {
|
if targets.iter().all(|t| matches!(t.node, ast::ExprKind::Name { .. })) {
|
||||||
if let ast::StmtKind::Assign { targets, value, .. } = node.node {
|
if let ast::StmtKind::Assign { targets, value, .. } = node.node {
|
||||||
let value = self.fold_expr(*value)?;
|
let value = self.fold_expr(*value)?;
|
||||||
|
@ -158,6 +158,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
targets,
|
targets,
|
||||||
value: Box::new(value),
|
value: Box::new(value),
|
||||||
type_comment: None,
|
type_comment: None,
|
||||||
|
config_comment: config_comment.clone()
|
||||||
},
|
},
|
||||||
custom: None,
|
custom: None,
|
||||||
});
|
});
|
||||||
|
@ -198,7 +199,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::StmtKind::AnnAssign { .. } | ast::StmtKind::Expr { .. } => {}
|
ast::StmtKind::AnnAssign { .. } | ast::StmtKind::Expr { .. } => {}
|
||||||
ast::StmtKind::Break | ast::StmtKind::Continue | ast::StmtKind::Pass => {}
|
ast::StmtKind::Break { .. } | ast::StmtKind::Continue { .. } | ast::StmtKind::Pass { .. } => {}
|
||||||
ast::StmtKind::With { items, .. } => {
|
ast::StmtKind::With { items, .. } => {
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
let ty = item.context_expr.custom.unwrap();
|
let ty = item.context_expr.custom.unwrap();
|
||||||
|
@ -272,7 +273,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::StmtKind::Return { value } => match (value, self.function_data.return_type) {
|
ast::StmtKind::Return { value, .. } => match (value, self.function_data.return_type) {
|
||||||
(Some(v), Some(v1)) => {
|
(Some(v), Some(v1)) => {
|
||||||
self.unify(v.custom.unwrap(), v1, &v.location)?;
|
self.unify(v.custom.unwrap(), v1, &v.location)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
use lalrpop_util::ParseError;
|
||||||
|
use nac3ast::*;
|
||||||
|
use crate::ast::Ident;
|
||||||
|
use crate::ast::Location;
|
||||||
|
use crate::token::Tok;
|
||||||
|
use crate::error::*;
|
||||||
|
|
||||||
|
pub fn make_config_comment(
|
||||||
|
com_loc: Location,
|
||||||
|
stmt_loc: Location,
|
||||||
|
nac3com_above: Vec<(Ident, Tok)>,
|
||||||
|
nac3com_end: Option<Ident>
|
||||||
|
) -> Result<Vec<Ident>, ParseError<Location, Tok, LexicalError>> {
|
||||||
|
if com_loc.column() != stmt_loc.column() {
|
||||||
|
return Err(ParseError::User {
|
||||||
|
error: LexicalError {
|
||||||
|
location: com_loc,
|
||||||
|
error: LexicalErrorType::OtherError(
|
||||||
|
format!(
|
||||||
|
"config comment at top must have the same indentation with what it applies, comment at {}, statement at {}",
|
||||||
|
com_loc,
|
||||||
|
stmt_loc,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
Ok(
|
||||||
|
nac3com_above
|
||||||
|
.into_iter()
|
||||||
|
.map(|(com, _)| com)
|
||||||
|
.chain(nac3com_end.map_or_else(|| vec![].into_iter(), |com| vec![com].into_iter()))
|
||||||
|
.collect()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_small_stmt<U>(stmts: &mut [Stmt<U>], nac3com_above: Vec<(Ident, Tok)>, nac3com_end: Option<Ident>, com_above_loc: Location) -> Result<(), ParseError<Location, Tok, LexicalError>> {
|
||||||
|
if com_above_loc.column() != stmts[0].location.column() {
|
||||||
|
return Err(ParseError::User {
|
||||||
|
error: LexicalError {
|
||||||
|
location: com_above_loc,
|
||||||
|
error: LexicalErrorType::OtherError(
|
||||||
|
format!(
|
||||||
|
"config comment at top must have the same indentation with what it applies, comment at {}, statement at {}",
|
||||||
|
com_above_loc,
|
||||||
|
stmts[0].location,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
apply_config_comments(
|
||||||
|
&mut stmts[0],
|
||||||
|
nac3com_above
|
||||||
|
.into_iter()
|
||||||
|
.map(|(com, _)| com).collect()
|
||||||
|
);
|
||||||
|
apply_config_comments(
|
||||||
|
stmts.last_mut().unwrap(),
|
||||||
|
nac3com_end.map_or_else(Vec::new, |com| vec![com])
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_config_comments<U>(stmt: &mut Stmt<U>, comments: Vec<Ident>) {
|
||||||
|
match &mut stmt.node {
|
||||||
|
StmtKind::Pass { config_comment, .. }
|
||||||
|
| StmtKind::Delete { config_comment, .. }
|
||||||
|
| StmtKind::Expr { config_comment, .. }
|
||||||
|
| StmtKind::Assign { config_comment, .. }
|
||||||
|
| StmtKind::AugAssign { config_comment, .. }
|
||||||
|
| StmtKind::AnnAssign { config_comment, .. }
|
||||||
|
| StmtKind::Break { config_comment, .. }
|
||||||
|
| StmtKind::Continue { config_comment, .. }
|
||||||
|
| StmtKind::Return { config_comment, .. }
|
||||||
|
| StmtKind::Raise { config_comment, .. }
|
||||||
|
| StmtKind::Import { config_comment, .. }
|
||||||
|
| StmtKind::ImportFrom { config_comment, .. }
|
||||||
|
| StmtKind::Global { config_comment, .. }
|
||||||
|
| StmtKind::Nonlocal { config_comment, .. }
|
||||||
|
| StmtKind::Assert { config_comment, .. } => config_comment.extend(comments),
|
||||||
|
|
||||||
|
_ => { unreachable!("only small statements should call this function") }
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,6 +65,7 @@ pub struct Lexer<T: Iterator<Item = char>> {
|
||||||
chr1: Option<char>,
|
chr1: Option<char>,
|
||||||
chr2: Option<char>,
|
chr2: Option<char>,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
config_comment_prefix: Option<&'static str>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! {
|
pub static KEYWORDS: phf::Map<&'static str, Tok> = phf::phf_map! {
|
||||||
|
@ -196,6 +197,7 @@ where
|
||||||
location: start,
|
location: start,
|
||||||
chr1: None,
|
chr1: None,
|
||||||
chr2: None,
|
chr2: None,
|
||||||
|
config_comment_prefix: Some(" nac3:")
|
||||||
};
|
};
|
||||||
lxr.next_char();
|
lxr.next_char();
|
||||||
lxr.next_char();
|
lxr.next_char();
|
||||||
|
@ -415,17 +417,45 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skip everything until end of line
|
/// Skip everything until end of line, may produce nac3 pseudocomment
|
||||||
fn lex_comment(&mut self) {
|
fn lex_comment(&mut self) -> Option<Spanned> {
|
||||||
self.next_char();
|
self.next_char();
|
||||||
|
// if possibly nac3 pseudocomment, special handling for `# nac3:`
|
||||||
|
let (mut prefix, mut is_comment) = self
|
||||||
|
.config_comment_prefix
|
||||||
|
.map_or_else(|| ("".chars(), false), |v| (v.chars(), true));
|
||||||
|
// for the correct location of config comment
|
||||||
|
let mut start_loc = self.location;
|
||||||
|
start_loc.go_left();
|
||||||
loop {
|
loop {
|
||||||
match self.chr0 {
|
match self.chr0 {
|
||||||
Some('\n') => return,
|
Some('\n') => return None,
|
||||||
Some(_) => {}
|
None => return None,
|
||||||
None => return,
|
Some(c) => {
|
||||||
|
if let (true, Some(p)) = (is_comment, prefix.next()) {
|
||||||
|
is_comment = is_comment && c == p
|
||||||
|
} else {
|
||||||
|
// done checking prefix, if is comment then return the spanned
|
||||||
|
if is_comment {
|
||||||
|
let mut content = String::new();
|
||||||
|
loop {
|
||||||
|
match self.chr0 {
|
||||||
|
Some('\n') | None => break,
|
||||||
|
Some(c) => content.push(c),
|
||||||
|
}
|
||||||
|
self.next_char();
|
||||||
|
}
|
||||||
|
return Some((
|
||||||
|
start_loc,
|
||||||
|
Tok::ConfigComment { content: content.trim().into() },
|
||||||
|
self.location
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.next_char();
|
self.next_char();
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unicode_literal(&mut self, literal_number: usize) -> Result<char, LexicalError> {
|
fn unicode_literal(&mut self, literal_number: usize) -> Result<char, LexicalError> {
|
||||||
|
@ -658,10 +688,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given we are at the start of a line, count the number of spaces and/or tabs until the first character.
|
/// Given we are at the start of a line, count the number of spaces and/or tabs until the first character.
|
||||||
fn eat_indentation(&mut self) -> Result<IndentationLevel, LexicalError> {
|
fn eat_indentation(&mut self) -> Result<(IndentationLevel, Option<Spanned>), LexicalError> {
|
||||||
// Determine indentation:
|
// Determine indentation:
|
||||||
let mut spaces: usize = 0;
|
let mut spaces: usize = 0;
|
||||||
let mut tabs: usize = 0;
|
let mut tabs: usize = 0;
|
||||||
|
let mut nac3comment: Option<Spanned> = None;
|
||||||
loop {
|
loop {
|
||||||
match self.chr0 {
|
match self.chr0 {
|
||||||
Some(' ') => {
|
Some(' ') => {
|
||||||
|
@ -693,7 +724,14 @@ where
|
||||||
tabs += 1;
|
tabs += 1;
|
||||||
}
|
}
|
||||||
Some('#') => {
|
Some('#') => {
|
||||||
self.lex_comment();
|
nac3comment = self.lex_comment();
|
||||||
|
// if is nac3comment, we need to add newline, so it is not begin of line
|
||||||
|
// and we should break from the loop, else in the next loop it will be
|
||||||
|
// regarded as a empty line
|
||||||
|
if nac3comment.is_some() {
|
||||||
|
self.at_begin_of_line = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
spaces = 0;
|
spaces = 0;
|
||||||
tabs = 0;
|
tabs = 0;
|
||||||
}
|
}
|
||||||
|
@ -722,11 +760,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(IndentationLevel { tabs, spaces })
|
Ok((IndentationLevel { tabs, spaces }, nac3comment))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_indentations(&mut self) -> Result<(), LexicalError> {
|
fn handle_indentations(&mut self) -> Result<(), LexicalError> {
|
||||||
let indentation_level = self.eat_indentation()?;
|
let eat_result = self.eat_indentation()?;
|
||||||
|
let indentation_level = eat_result.0;
|
||||||
|
|
||||||
if self.nesting == 0 {
|
if self.nesting == 0 {
|
||||||
// Determine indent or dedent:
|
// Determine indent or dedent:
|
||||||
|
@ -770,6 +809,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(comment) = eat_result.1 {
|
||||||
|
self.emit(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -833,7 +876,9 @@ where
|
||||||
self.emit(number);
|
self.emit(number);
|
||||||
}
|
}
|
||||||
'#' => {
|
'#' => {
|
||||||
self.lex_comment();
|
if let Some(c) = self.lex_comment() {
|
||||||
|
self.emit(c);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
'"' | '\'' => {
|
'"' | '\'' => {
|
||||||
let string = self.lex_string(false, false, false, false)?;
|
let string = self.lex_string(false, false, false, false)?;
|
||||||
|
@ -1287,6 +1332,85 @@ mod tests {
|
||||||
lexer.map(|x| x.unwrap().1).collect()
|
lexer.map(|x| x.unwrap().1).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_nac3comment() {
|
||||||
|
let src = "\
|
||||||
|
a: int32
|
||||||
|
# nac3:
|
||||||
|
b: int64";
|
||||||
|
let tokens = lex_source(src);
|
||||||
|
assert_eq!(
|
||||||
|
tokens,
|
||||||
|
vec![
|
||||||
|
Tok::Name { name: "a".into() },
|
||||||
|
Tok::Colon,
|
||||||
|
Tok::Name { name: "int32".into() },
|
||||||
|
Tok::Newline,
|
||||||
|
Tok::ConfigComment { content: "".into() },
|
||||||
|
Tok::Newline,
|
||||||
|
Tok::Name { name: "b".into() },
|
||||||
|
Tok::Colon,
|
||||||
|
Tok::Name { name: "int64".into() },
|
||||||
|
Tok::Newline,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_class_lex_with_nac3comment() {
|
||||||
|
use Tok::*;
|
||||||
|
let source = "\
|
||||||
|
class Foo(A, B):
|
||||||
|
# normal comment
|
||||||
|
# nac3: no indent
|
||||||
|
# nac3: correct indent
|
||||||
|
b: int32
|
||||||
|
a: int32 # nac3: no need indent
|
||||||
|
def __init__(self):
|
||||||
|
pass";
|
||||||
|
let tokens = lex_source(source);
|
||||||
|
assert_eq!(
|
||||||
|
tokens,
|
||||||
|
vec![
|
||||||
|
Class,
|
||||||
|
Name { name: "Foo".into() },
|
||||||
|
Lpar,
|
||||||
|
Name { name: "A".into() },
|
||||||
|
Comma,
|
||||||
|
Name { name: "B".into() },
|
||||||
|
Rpar,
|
||||||
|
Colon,
|
||||||
|
Newline,
|
||||||
|
ConfigComment { content: "no indent".into() },
|
||||||
|
Newline,
|
||||||
|
Indent,
|
||||||
|
ConfigComment { content: "correct indent".into() },
|
||||||
|
Newline,
|
||||||
|
Name { name: "b".into() },
|
||||||
|
Colon,
|
||||||
|
Name { name: "int32".into() },
|
||||||
|
Newline,
|
||||||
|
Name { name: "a".into() },
|
||||||
|
Colon,
|
||||||
|
Name { name: "int32".into() },
|
||||||
|
ConfigComment { content: "no need indent".into() },
|
||||||
|
Newline,
|
||||||
|
Def,
|
||||||
|
Name { name: "__init__".into() },
|
||||||
|
Lpar,
|
||||||
|
Name { name: "self".into() },
|
||||||
|
Rpar,
|
||||||
|
Colon,
|
||||||
|
Newline,
|
||||||
|
Indent,
|
||||||
|
Pass,
|
||||||
|
Newline,
|
||||||
|
Dedent,
|
||||||
|
Dedent
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_newline_processor() {
|
fn test_newline_processor() {
|
||||||
// Escape \ followed by \n (by removal):
|
// Escape \ followed by \n (by removal):
|
||||||
|
|
|
@ -32,3 +32,4 @@ lalrpop_mod!(
|
||||||
python
|
python
|
||||||
);
|
);
|
||||||
pub mod token;
|
pub mod token;
|
||||||
|
pub mod config_comment_helper;
|
||||||
|
|
|
@ -164,4 +164,67 @@ class Foo(A, B):
|
||||||
let parse_ast = parse_expression(&source).unwrap();
|
let parse_ast = parse_expression(&source).unwrap();
|
||||||
insta::assert_debug_snapshot!(parse_ast);
|
insta::assert_debug_snapshot!(parse_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_more_comment() {
|
||||||
|
let source = "\
|
||||||
|
a: int # nac3: sf1
|
||||||
|
# nac3: sdf4
|
||||||
|
for i in (1, '12'): # nac3: sf2
|
||||||
|
a: int
|
||||||
|
# nac3: 3
|
||||||
|
# nac3: 5
|
||||||
|
while i < 2: # nac3: 4
|
||||||
|
# nac3: real pass
|
||||||
|
pass
|
||||||
|
# nac3: expr1
|
||||||
|
# nac3: expr3
|
||||||
|
1 + 2 # nac3: expr2
|
||||||
|
# nac3: if3
|
||||||
|
# nac3: if1
|
||||||
|
if 1: # nac3: if2
|
||||||
|
3";
|
||||||
|
insta::assert_debug_snapshot!(parse_program(&source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sample_comment() {
|
||||||
|
let source = "\
|
||||||
|
# nac3: while1
|
||||||
|
# nac3: while2
|
||||||
|
# normal comment
|
||||||
|
while test: # nac3: while3
|
||||||
|
# nac3: simple assign0
|
||||||
|
a = 3 # nac3: simple assign1
|
||||||
|
";
|
||||||
|
insta::assert_debug_snapshot!(parse_program(&source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comment_ambiguity() {
|
||||||
|
let source = "\
|
||||||
|
if a: d; # nac3: for d
|
||||||
|
if b: c # nac3: for c
|
||||||
|
if d: # nac3: for if d
|
||||||
|
b; b + 3; # nac3: for b + 3
|
||||||
|
a = 3; a + 3; b = a; # nac3: notif
|
||||||
|
# nac3: smallsingle1
|
||||||
|
# nac3: smallsingle3
|
||||||
|
aa = 3 # nac3: smallsingle2
|
||||||
|
if a: # nac3: small2
|
||||||
|
a
|
||||||
|
for i in a: # nac3: for1
|
||||||
|
pass
|
||||||
|
";
|
||||||
|
insta::assert_debug_snapshot!(parse_program(&source).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_comment_should_fail() {
|
||||||
|
let source = "\
|
||||||
|
if a: # nac3: something
|
||||||
|
a = 3
|
||||||
|
";
|
||||||
|
assert!(parse_program(&source).is_err());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,11 @@ use crate::ast;
|
||||||
use crate::fstring::parse_located_fstring;
|
use crate::fstring::parse_located_fstring;
|
||||||
use crate::function::{ArgumentList, parse_args, parse_params};
|
use crate::function::{ArgumentList, parse_args, parse_params};
|
||||||
use crate::error::LexicalError;
|
use crate::error::LexicalError;
|
||||||
|
use crate::error::LexicalErrorType;
|
||||||
use crate::lexer;
|
use crate::lexer;
|
||||||
|
use crate::config_comment_helper::*;
|
||||||
|
|
||||||
|
use lalrpop_util::ParseError;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
grammar;
|
grammar;
|
||||||
|
@ -47,10 +50,11 @@ Statement: ast::Suite = {
|
||||||
};
|
};
|
||||||
|
|
||||||
SimpleStatement: ast::Suite = {
|
SimpleStatement: ast::Suite = {
|
||||||
<s1:SmallStatement> <s2:(";" SmallStatement)*> ";"? "\n" => {
|
<com_loc:@L> <nac3com_above:(config_comment "\n")*> <s1:SmallStatement> <s2:(";" SmallStatement)*> ";"? <nac3com_end:config_comment?> "\n" =>? {
|
||||||
let mut statements = vec![s1];
|
let mut statements = vec![s1];
|
||||||
statements.extend(s2.into_iter().map(|e| e.1));
|
statements.extend(s2.into_iter().map(|e| e.1));
|
||||||
statements
|
handle_small_stmt(&mut statements, nac3com_above, nac3com_end, com_loc)?;
|
||||||
|
Ok(statements)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +74,7 @@ PassStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
custom: (),
|
||||||
node: ast::StmtKind::Pass,
|
node: ast::StmtKind::Pass { config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -80,7 +84,7 @@ DelStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
location,
|
location,
|
||||||
custom: (),
|
custom: (),
|
||||||
node: ast::StmtKind::Delete { targets },
|
node: ast::StmtKind::Delete { targets, config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -92,7 +96,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Expr { value: Box::new(expression) }
|
node: ast::StmtKind::Expr { value: Box::new(expression), config_comment: vec![] }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut targets = vec![expression];
|
let mut targets = vec![expression];
|
||||||
|
@ -107,7 +111,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Assign { targets, value, type_comment: None },
|
node: ast::StmtKind::Assign { targets, value, type_comment: None, config_comment: vec![] },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -118,7 +122,8 @@ ExpressionStatement: ast::Stmt = {
|
||||||
node: ast::StmtKind::AugAssign {
|
node: ast::StmtKind::AugAssign {
|
||||||
target: Box::new(target),
|
target: Box::new(target),
|
||||||
op,
|
op,
|
||||||
value: Box::new(rhs)
|
value: Box::new(rhs),
|
||||||
|
config_comment: vec![],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -132,6 +137,7 @@ ExpressionStatement: ast::Stmt = {
|
||||||
annotation: Box::new(annotation),
|
annotation: Box::new(annotation),
|
||||||
value: rhs.map(Box::new),
|
value: rhs.map(Box::new),
|
||||||
simple,
|
simple,
|
||||||
|
config_comment: vec![],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -187,28 +193,28 @@ FlowStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Break,
|
node: ast::StmtKind::Break { config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "continue" => {
|
<location:@L> "continue" => {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Continue,
|
node: ast::StmtKind::Continue { config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "return" <value:TestList?> => {
|
<location:@L> "return" <value:TestList?> => {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Return { value: value.map(Box::new) },
|
node: ast::StmtKind::Return { value: value.map(Box::new), config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> <expression:YieldExpr> => {
|
<location:@L> <expression:YieldExpr> => {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Expr { value: Box::new(expression) },
|
node: ast::StmtKind::Expr { value: Box::new(expression), config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RaiseStatement,
|
RaiseStatement,
|
||||||
|
@ -219,14 +225,14 @@ RaiseStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Raise { exc: None, cause: None },
|
node: ast::StmtKind::Raise { exc: None, cause: None, config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "raise" <t:Test> <c:("from" Test)?> => {
|
<location:@L> "raise" <t:Test> <c:("from" Test)?> => {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Raise { exc: Some(Box::new(t)), cause: c.map(|x| Box::new(x.1)) },
|
node: ast::StmtKind::Raise { exc: Some(Box::new(t)), cause: c.map(|x| Box::new(x.1)), config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -236,7 +242,7 @@ ImportStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Import { names },
|
node: ast::StmtKind::Import { names, config_comment: vec![] },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> => {
|
<location:@L> "from" <source:ImportFromLocation> "import" <names: ImportAsNames> => {
|
||||||
|
@ -247,7 +253,8 @@ ImportStatement: ast::Stmt = {
|
||||||
node: ast::StmtKind::ImportFrom {
|
node: ast::StmtKind::ImportFrom {
|
||||||
level,
|
level,
|
||||||
module: module.map(|s| s.into()),
|
module: module.map(|s| s.into()),
|
||||||
names
|
names,
|
||||||
|
config_comment: vec![]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -301,7 +308,7 @@ GlobalStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Global { names }
|
node: ast::StmtKind::Global { names, config_comment: vec![] }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -311,7 +318,7 @@ NonlocalStatement: ast::Stmt = {
|
||||||
ast::Stmt {
|
ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Nonlocal { names }
|
node: ast::StmtKind::Nonlocal { names, config_comment: vec![] }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -323,7 +330,8 @@ AssertStatement: ast::Stmt = {
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Assert {
|
node: ast::StmtKind::Assert {
|
||||||
test: Box::new(test),
|
test: Box::new(test),
|
||||||
msg: msg.map(|e| Box::new(e.1))
|
msg: msg.map(|e| Box::new(e.1)),
|
||||||
|
config_comment: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -340,7 +348,7 @@ CompoundStatement: ast::Stmt = {
|
||||||
};
|
};
|
||||||
|
|
||||||
IfStatement: ast::Stmt = {
|
IfStatement: ast::Stmt = {
|
||||||
<location:@L> "if" <test:NamedExpressionTest> ":" <body:Suite> <s2:(@L "elif" NamedExpressionTest ":" Suite)*> <s3:("else" ":" Suite)?> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> "if" <test:NamedExpressionTest> ":" <nac3com_end:config_comment?> <body:Suite> <s2:(@L "elif" NamedExpressionTest ":" Suite)*> <s3:("else" ":" Suite)?> =>? {
|
||||||
// Determine last else:
|
// Determine last else:
|
||||||
let mut last = s3.map(|s| s.2).unwrap_or_default();
|
let mut last = s3.map(|s| s.2).unwrap_or_default();
|
||||||
|
|
||||||
|
@ -349,54 +357,74 @@ IfStatement: ast::Stmt = {
|
||||||
let x = ast::Stmt {
|
let x = ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location: i.0,
|
location: i.0,
|
||||||
node: ast::StmtKind::If { test: Box::new(i.2), body: i.4, orelse: last },
|
node: ast::StmtKind::If { test: Box::new(i.2), body: i.4, orelse: last, config_comment: vec![] },
|
||||||
};
|
};
|
||||||
last = vec![x];
|
last = vec![x];
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Stmt {
|
Ok(ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::If { test: Box::new(test), body, orelse: last }
|
node: ast::StmtKind::If {
|
||||||
}
|
test: Box::new(test),
|
||||||
|
body,
|
||||||
|
orelse: last,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
WhileStatement: ast::Stmt = {
|
WhileStatement: ast::Stmt = {
|
||||||
<location:@L> "while" <test:NamedExpressionTest> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> "while" <test:NamedExpressionTest> ":" <nac3com_end:config_comment?> <body:Suite> <s2:("else" ":" Suite)?> =>? {
|
||||||
let orelse = s2.map(|s| s.2).unwrap_or_default();
|
let orelse = s2.map(|s| s.2).unwrap_or_default();
|
||||||
ast::Stmt {
|
Ok(ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::While {
|
node: ast::StmtKind::While {
|
||||||
test: Box::new(test),
|
test: Box::new(test),
|
||||||
body,
|
body,
|
||||||
orelse
|
orelse,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ForStatement: ast::Stmt = {
|
ForStatement: ast::Stmt = {
|
||||||
<location:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:TestList> ":" <body:Suite> <s2:("else" ":" Suite)?> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> <is_async:"async"?> "for" <target:ExpressionList> "in" <iter:TestList> ":" <nac3com_end:config_comment?> <body:Suite> <s2:("else" ":" Suite)?> =>? {
|
||||||
let orelse = s2.map(|s| s.2).unwrap_or_default();
|
let orelse = s2.map(|s| s.2).unwrap_or_default();
|
||||||
let target = Box::new(target);
|
let target = Box::new(target);
|
||||||
let iter = Box::new(iter);
|
let iter = Box::new(iter);
|
||||||
let type_comment = None;
|
let type_comment = None;
|
||||||
let node = if is_async.is_some() {
|
let node = if is_async.is_some() {
|
||||||
ast::StmtKind::AsyncFor { target, iter, body, orelse, type_comment }
|
ast::StmtKind::AsyncFor {
|
||||||
|
target,
|
||||||
|
iter,
|
||||||
|
body,
|
||||||
|
orelse,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ast::StmtKind::For { target, iter, body, orelse, type_comment }
|
ast::StmtKind::For {
|
||||||
|
target,
|
||||||
|
iter,
|
||||||
|
body,
|
||||||
|
orelse,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, node)
|
Ok(ast::Stmt::new(location, node))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
TryStatement: ast::Stmt = {
|
TryStatement: ast::Stmt = {
|
||||||
<location:@L> "try" ":" <body:Suite> <handlers:ExceptClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> "try" ":" <nac3com_end:config_comment?> <body:Suite> <handlers:ExceptClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> =>? {
|
||||||
let orelse = else_suite.map(|s| s.2).unwrap_or_default();
|
let orelse = else_suite.map(|s| s.2).unwrap_or_default();
|
||||||
let finalbody = finally.map(|s| s.2).unwrap_or_default();
|
let finalbody = finally.map(|s| s.2).unwrap_or_default();
|
||||||
ast::Stmt {
|
Ok(ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Try {
|
node: ast::StmtKind::Try {
|
||||||
|
@ -404,14 +432,15 @@ TryStatement: ast::Stmt = {
|
||||||
handlers,
|
handlers,
|
||||||
orelse,
|
orelse,
|
||||||
finalbody,
|
finalbody,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
<location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> "try" ":" <nac3com_end:config_comment?> <body:Suite> <finally:("finally" ":" Suite)> =>? {
|
||||||
let handlers = vec![];
|
let handlers = vec![];
|
||||||
let orelse = vec![];
|
let orelse = vec![];
|
||||||
let finalbody = finally.2;
|
let finalbody = finally.2;
|
||||||
ast::Stmt {
|
Ok(ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::Try {
|
node: ast::StmtKind::Try {
|
||||||
|
@ -419,8 +448,9 @@ TryStatement: ast::Stmt = {
|
||||||
handlers,
|
handlers,
|
||||||
orelse,
|
orelse,
|
||||||
finalbody,
|
finalbody,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -448,14 +478,24 @@ ExceptClause: ast::Excepthandler = {
|
||||||
};
|
};
|
||||||
|
|
||||||
WithStatement: ast::Stmt = {
|
WithStatement: ast::Stmt = {
|
||||||
<location:@L> <is_async:"async"?> "with" <items:OneOrMore<WithItem>> ":" <body:Suite> => {
|
<location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> <is_async:"async"?> "with" <items:OneOrMore<WithItem>> ":" <nac3com_end:config_comment?> <body:Suite> =>? {
|
||||||
let type_comment = None;
|
let type_comment = None;
|
||||||
let node = if is_async.is_some() {
|
let node = if is_async.is_some() {
|
||||||
ast::StmtKind::AsyncWith { items, body, type_comment }
|
ast::StmtKind::AsyncWith {
|
||||||
|
items,
|
||||||
|
body,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ast::StmtKind::With { items, body, type_comment }
|
ast::StmtKind::With {
|
||||||
|
items,
|
||||||
|
body,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, node)
|
Ok(ast::Stmt::new(location, node))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -468,16 +508,32 @@ WithItem: ast::Withitem = {
|
||||||
};
|
};
|
||||||
|
|
||||||
FuncDef: ast::Stmt = {
|
FuncDef: ast::Stmt = {
|
||||||
<decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <body:Suite> => {
|
<decorator_list:Decorator*> <location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test)?> ":" <nac3com_end:config_comment?> <body:Suite> =>? {
|
||||||
let args = Box::new(args);
|
let args = Box::new(args);
|
||||||
let returns = r.map(|x| Box::new(x.1));
|
let returns = r.map(|x| Box::new(x.1));
|
||||||
let type_comment = None;
|
let type_comment = None;
|
||||||
let node = if is_async.is_some() {
|
let node = if is_async.is_some() {
|
||||||
ast::StmtKind::AsyncFunctionDef { name, args, body, decorator_list, returns, type_comment }
|
ast::StmtKind::AsyncFunctionDef {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
body,
|
||||||
|
decorator_list,
|
||||||
|
returns,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ast::StmtKind::FunctionDef { name, args, body, decorator_list, returns, type_comment }
|
ast::StmtKind::FunctionDef {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
body,
|
||||||
|
decorator_list,
|
||||||
|
returns,
|
||||||
|
type_comment,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ast::Stmt::new(location, node)
|
Ok(ast::Stmt::new(location, node))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -615,12 +671,12 @@ KwargParameter<ArgType>: Option<Box<ast::Arg>> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
ClassDef: ast::Stmt = {
|
ClassDef: ast::Stmt = {
|
||||||
<decorator_list:Decorator*> <location:@L> "class" <name:Identifier> <a:("(" ArgumentList ")")?> ":" <body:Suite> => {
|
<decorator_list:Decorator*> <location:@L> <nac3com_above:(config_comment "\n")*> <stmt_loc:@L> "class" <name:Identifier> <a:("(" ArgumentList ")")?> ":" <nac3com_end:config_comment?> <body:Suite> =>? {
|
||||||
let (bases, keywords) = match a {
|
let (bases, keywords) = match a {
|
||||||
Some((_, arg, _)) => (arg.args, arg.keywords),
|
Some((_, arg, _)) => (arg.args, arg.keywords),
|
||||||
None => (vec![], vec![]),
|
None => (vec![], vec![]),
|
||||||
};
|
};
|
||||||
ast::Stmt {
|
Ok(ast::Stmt {
|
||||||
custom: (),
|
custom: (),
|
||||||
location,
|
location,
|
||||||
node: ast::StmtKind::ClassDef {
|
node: ast::StmtKind::ClassDef {
|
||||||
|
@ -629,8 +685,9 @@ ClassDef: ast::Stmt = {
|
||||||
keywords,
|
keywords,
|
||||||
body,
|
body,
|
||||||
decorator_list,
|
decorator_list,
|
||||||
|
config_comment: make_config_comment(location, stmt_loc, nac3com_above, nac3com_end)?
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1301,6 +1358,7 @@ extern {
|
||||||
string => lexer::Tok::String { value: <String>, is_fstring: <bool> },
|
string => lexer::Tok::String { value: <String>, is_fstring: <bool> },
|
||||||
bytes => lexer::Tok::Bytes { value: <Vec<u8>> },
|
bytes => lexer::Tok::Bytes { value: <Vec<u8>> },
|
||||||
name => lexer::Tok::Name { name: <ast::StrRef> },
|
name => lexer::Tok::Name { name: <ast::StrRef> },
|
||||||
|
config_comment => lexer::Tok::ConfigComment { content: <ast::StrRef> },
|
||||||
"\n" => lexer::Tok::Newline,
|
"\n" => lexer::Tok::Newline,
|
||||||
";" => lexer::Tok::Semi,
|
";" => lexer::Tok::Semi,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,448 @@
|
||||||
|
---
|
||||||
|
source: nac3parser/src/parser.rs
|
||||||
|
expression: parse_program(&source).unwrap()
|
||||||
|
|
||||||
|
---
|
||||||
|
[
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: If {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "d",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [
|
||||||
|
"for d",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 2,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: If {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 2,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "b",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 2,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 2,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "c",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [
|
||||||
|
"for c",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: If {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "d",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "b",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 10,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: BinOp {
|
||||||
|
left: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "b",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
op: Add,
|
||||||
|
right: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 12,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [
|
||||||
|
"for b + 3",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [
|
||||||
|
"for if d",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Assign {
|
||||||
|
targets: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 10,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: BinOp {
|
||||||
|
left: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
op: Add,
|
||||||
|
right: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 12,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 15,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Assign {
|
||||||
|
targets: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 15,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "b",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 19,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [
|
||||||
|
"notif",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 8,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Assign {
|
||||||
|
targets: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 8,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "aa",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 8,
|
||||||
|
column: 6,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [
|
||||||
|
"smallsingle1",
|
||||||
|
"smallsingle3",
|
||||||
|
"smallsingle2",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 9,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: If {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 9,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 10,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 10,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [
|
||||||
|
"small2",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 11,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: For {
|
||||||
|
target: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 11,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "i",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
iter: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 11,
|
||||||
|
column: 10,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 12,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Pass {
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [
|
||||||
|
"for1",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
|
@ -0,0 +1,313 @@
|
||||||
|
---
|
||||||
|
source: nac3parser/src/parser.rs
|
||||||
|
expression: parse_program(&source).unwrap()
|
||||||
|
|
||||||
|
---
|
||||||
|
[
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: AnnAssign {
|
||||||
|
target: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
annotation: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 4,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "int",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
value: None,
|
||||||
|
simple: true,
|
||||||
|
config_comment: [
|
||||||
|
"sf1",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 2,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: For {
|
||||||
|
target: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "i",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
iter: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 11,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Tuple {
|
||||||
|
elts: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 11,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 3,
|
||||||
|
column: 15,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Str(
|
||||||
|
"12",
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: AnnAssign {
|
||||||
|
target: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
annotation: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "int",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
value: None,
|
||||||
|
simple: true,
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [
|
||||||
|
"sdf4",
|
||||||
|
"sf2",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 5,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: While {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 7,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Compare {
|
||||||
|
left: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 7,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "i",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ops: [
|
||||||
|
Lt,
|
||||||
|
],
|
||||||
|
comparators: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 7,
|
||||||
|
column: 11,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 9,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Pass {
|
||||||
|
config_comment: [
|
||||||
|
"real pass",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 12,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 12,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: BinOp {
|
||||||
|
left: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 12,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
op: Add,
|
||||||
|
right: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 12,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [
|
||||||
|
"expr1",
|
||||||
|
"expr3",
|
||||||
|
"expr2",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 13,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: If {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 15,
|
||||||
|
column: 8,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 16,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Expr {
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 16,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [
|
||||||
|
"if3",
|
||||||
|
"if1",
|
||||||
|
"if2",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [
|
||||||
|
"3",
|
||||||
|
"5",
|
||||||
|
"4",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_program(&source).unwrap()
|
expression: parse_program(&source).unwrap()
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
Located {
|
Located {
|
||||||
|
@ -74,12 +75,15 @@ expression: parse_program(&source).unwrap()
|
||||||
column: 3,
|
column: 3,
|
||||||
},
|
},
|
||||||
custom: (),
|
custom: (),
|
||||||
node: Pass,
|
node: Pass {
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
decorator_list: [],
|
decorator_list: [],
|
||||||
returns: None,
|
returns: None,
|
||||||
type_comment: None,
|
type_comment: None,
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Located {
|
Located {
|
||||||
|
@ -145,16 +149,20 @@ expression: parse_program(&source).unwrap()
|
||||||
column: 3,
|
column: 3,
|
||||||
},
|
},
|
||||||
custom: (),
|
custom: (),
|
||||||
node: Pass,
|
node: Pass {
|
||||||
|
config_comment: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
decorator_list: [],
|
decorator_list: [],
|
||||||
returns: None,
|
returns: None,
|
||||||
type_comment: None,
|
type_comment: None,
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
decorator_list: [],
|
decorator_list: [],
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_ast
|
expression: parse_ast
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -45,6 +45,7 @@ expression: parse_ast
|
||||||
kind: None,
|
kind: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -90,6 +91,7 @@ expression: parse_ast
|
||||||
kind: None,
|
kind: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -114,12 +116,15 @@ expression: parse_ast
|
||||||
kind: None,
|
kind: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_ast
|
expression: parse_ast
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -73,6 +73,7 @@ expression: parse_ast
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_ast
|
expression: parse_ast
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
Located {
|
Located {
|
||||||
|
@ -85,6 +86,7 @@ expression: parse_ast
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_ast
|
expression: parse_ast
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -60,6 +60,7 @@ expression: parse_ast
|
||||||
keywords: [],
|
keywords: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_ast
|
expression: parse_ast
|
||||||
|
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
Located {
|
Located {
|
||||||
|
@ -46,6 +47,7 @@ expression: parse_ast
|
||||||
keywords: [],
|
keywords: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
---
|
---
|
||||||
source: parser/src/parser.rs
|
source: nac3parser/src/parser.rs
|
||||||
expression: parse_program(&source).unwrap()
|
expression: parse_program(&source).unwrap()
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -86,6 +86,7 @@ expression: parse_program(&source).unwrap()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type_comment: None,
|
type_comment: None,
|
||||||
|
config_comment: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
---
|
||||||
|
source: nac3parser/src/parser.rs
|
||||||
|
expression: parse_program(&source).unwrap()
|
||||||
|
|
||||||
|
---
|
||||||
|
[
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 1,
|
||||||
|
column: 1,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: While {
|
||||||
|
test: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 4,
|
||||||
|
column: 7,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "test",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
body: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 6,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Assign {
|
||||||
|
targets: [
|
||||||
|
Located {
|
||||||
|
location: Location {
|
||||||
|
row: 6,
|
||||||
|
column: 5,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Name {
|
||||||
|
id: "a",
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
value: Located {
|
||||||
|
location: Location {
|
||||||
|
row: 6,
|
||||||
|
column: 9,
|
||||||
|
},
|
||||||
|
custom: (),
|
||||||
|
node: Constant {
|
||||||
|
value: Int(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
kind: None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type_comment: None,
|
||||||
|
config_comment: [
|
||||||
|
"simple assign0",
|
||||||
|
"simple assign1",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
orelse: [],
|
||||||
|
config_comment: [
|
||||||
|
"while1",
|
||||||
|
"while2",
|
||||||
|
"while3",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
|
@ -13,6 +13,7 @@ pub enum Tok {
|
||||||
Complex { real: f64, imag: f64 },
|
Complex { real: f64, imag: f64 },
|
||||||
String { value: String, is_fstring: bool },
|
String { value: String, is_fstring: bool },
|
||||||
Bytes { value: Vec<u8> },
|
Bytes { value: Vec<u8> },
|
||||||
|
ConfigComment { content: ast::StrRef },
|
||||||
Newline,
|
Newline,
|
||||||
Indent,
|
Indent,
|
||||||
Dedent,
|
Dedent,
|
||||||
|
@ -134,6 +135,7 @@ impl fmt::Display for Tok {
|
||||||
}
|
}
|
||||||
f.write_str("\"")
|
f.write_str("\"")
|
||||||
}
|
}
|
||||||
|
ConfigComment { content } => write!(f, "ConfigComment: '{}'", ast::get_str_from_ref(&ast::get_str_ref_lock(), *content)),
|
||||||
Newline => f.write_str("Newline"),
|
Newline => f.write_str("Newline"),
|
||||||
Indent => f.write_str("Indent"),
|
Indent => f.write_str("Indent"),
|
||||||
Dedent => f.write_str("Dedent"),
|
Dedent => f.write_str("Dedent"),
|
||||||
|
|
Loading…
Reference in New Issue