77use super::ast;
88use super::lexer;
99use std::iter::FromIterator;
10- use std::str::FromStr;
1110
1211grammar;
1312
@@ -53,6 +52,8 @@ SmallStatement: ast::LocatedStatement = {
5352 DelStatement,
5453 FlowStatement,
5554 ImportStatement,
55+ GlobalStatement,
56+ NonlocalStatement,
5657 AssertStatement,
5758};
5859
@@ -282,6 +283,24 @@ DottedName: String = {
282283 },
283284};
284285
286+ GlobalStatement: ast::LocatedStatement = {
287+ <loc:@L> "global" <names:OneOrMore<Identifier>> => {
288+ ast::LocatedStatement {
289+ location: loc,
290+ node: ast::Statement::Global { names }
291+ }
292+ },
293+ };
294+
295+ NonlocalStatement: ast::LocatedStatement = {
296+ <loc:@L> "nonlocal" <names:OneOrMore<Identifier>> => {
297+ ast::LocatedStatement {
298+ location: loc,
299+ node: ast::Statement::Nonlocal { names }
300+ }
301+ },
302+ };
303+
285304AssertStatement: ast::LocatedStatement = {
286305 <loc:@L> "assert" <t:Test> <m: ("," Test)?> => {
287306 ast::LocatedStatement {
@@ -400,11 +419,7 @@ ExceptClause: ast::ExceptHandler = {
400419};
401420
402421WithStatement: ast::LocatedStatement = {
403- <loc:@L> "with" <i1:WithItem> <i2:("," WithItem)*> ":" <s:Suite> => {
404- let mut items = vec![i1];
405- for item in i2 {
406- items.push(item.1);
407- }
422+ <loc:@L> "with" <items:OneOrMore<WithItem>> ":" <s:Suite> => {
408423 ast::LocatedStatement {
409424 location: loc,
410425 node: ast::Statement::With { items: items, body: s },
@@ -808,10 +823,8 @@ Atom: ast::Expression = {
808823};
809824
810825TestListComp: Vec<ast::Expression> = {
811- <e:TestOrStarExpr> <e2:("," TestOrStarExpr)*> <_trailing_comma:","?> => {
812- let mut res = vec![e];
813- res.extend(e2.into_iter().map(|x| x.1));
814- res
826+ <e:OneOrMore<TestOrStarExpr>> <_trailing_comma:","?> => {
827+ e
815828 },
816829};
817830
@@ -825,10 +838,8 @@ TestListComp2: ast::Expression = {
825838};
826839
827840TestDict: Vec<(ast::Expression, ast::Expression)> = {
828- <e1:DictEntry> <e2:("," DictEntry)*> <_trailing_comma:","?> => {
829- let mut d = vec![e1];
830- d.extend(e2.into_iter().map(|x| x.1));
831- d
841+ <e1:OneOrMore<DictEntry>> <_trailing_comma:","?> => {
842+ e1
832843 }
833844};
834845
@@ -846,10 +857,8 @@ DictEntry: (ast::Expression, ast::Expression) = {
846857};
847858
848859TestSet: Vec<ast::Expression> = {
849- <e1:Test> <e2:("," Test)*> ","? => {
850- let mut e = vec![e1];
851- e.extend(e2.into_iter().map(|x| x.1));
852- e
860+ <e1:OneOrMore<Test>> ","? => {
861+ e1
853862 }
854863};
855864
@@ -962,14 +971,22 @@ Comma<T>: Vec<T> = {
962971 }
963972};
964973
965- Number: ast::Number = {
966- <s:number > => {
967- if s.contains(".") {
968- ast::Number::Float { value: f64::from_str(&s).unwrap() }
969- } else {
970- ast::Number::Integer { value: i32::from_str(&s).unwrap() }
974+ #[inline]
975+ OneOrMore<T>: Vec<T > = {
976+ <i1: T> <i2:("," T)*> => {
977+ let mut items = vec![i1];
978+ items.extend(i2.into_iter().map(|e| e.1));
979+ items
971980 }
972- }
981+ };
982+
983+ Number: ast::Number = {
984+ <s:int> => {
985+ ast::Number::Integer { value: s }
986+ },
987+ <s:float> => {
988+ ast::Number::Float { value: s }
989+ },
973990};
974991
975992StringConstant: ast::Expression = {
@@ -1052,12 +1069,14 @@ extern {
10521069 "finally" => lexer::Tok::Finally,
10531070 "for" => lexer::Tok::For,
10541071 "from" => lexer::Tok::From,
1072+ "global" => lexer::Tok::Global,
10551073 "if" => lexer::Tok::If,
10561074 "in" => lexer::Tok::In,
10571075 "is" => lexer::Tok::Is,
10581076 "import" => lexer::Tok::Import,
10591077 "from" => lexer::Tok::From,
10601078 "lambda" => lexer::Tok::Lambda,
1079+ "nonlocal" => lexer::Tok::Nonlocal,
10611080 "not" => lexer::Tok::Not,
10621081 "or" => lexer::Tok::Or,
10631082 "pass" => lexer::Tok::Pass,
@@ -1070,7 +1089,8 @@ extern {
10701089 "True" => lexer::Tok::True,
10711090 "False" => lexer::Tok::False,
10721091 "None" => lexer::Tok::None,
1073- number => lexer::Tok::Number { value: <String> },
1092+ int => lexer::Tok::Int { value: <i32> },
1093+ float => lexer::Tok::Float { value: <f64> },
10741094 string => lexer::Tok::String { value: <String> },
10751095 bytes => lexer::Tok::Bytes { value: <Vec<u8>> },
10761096 name => lexer::Tok::Name { name: <String> },