https://docs.python.org/3/reference/expressions.html#primaries primaries can be chained together, when they are chained the base is the previous primary
(&mut self, base: Option<Expression>)
| 2240 | // primaries can be chained together, when they are chained the base is the |
| 2241 | // previous primary |
| 2242 | fn parse_primary(&mut self, base: Option<Expression>) -> Result<Expression, ParsingError> { |
| 2243 | let next = self.peek_token(); |
| 2244 | let node = self.start_node(); |
| 2245 | let call_node = self.start_node(); |
| 2246 | let mut atom_or_primary = if let Some(base) = base { |
| 2247 | base |
| 2248 | } else if self.cur_kind().is_atom() { |
| 2249 | self.parse_atom()? |
| 2250 | } else { |
| 2251 | panic!("not a primary {:?}", self.cur_token()); |
| 2252 | }; |
| 2253 | |
| 2254 | let mut primary = if self.at(Kind::Dot) { |
| 2255 | self.parse_attribute_ref(node, atom_or_primary) |
| 2256 | } else if self.at(Kind::LeftBrace) { |
| 2257 | // https://docs.python.org/3/reference/expressions.html#slicings |
| 2258 | self.parse_subscript(atom_or_primary.get_node(), atom_or_primary) |
| 2259 | } else if self.eat(Kind::LeftParen) { |
| 2260 | // parse call |
| 2261 | // https://docs.python.org/3/reference/expressions.html#calls |
| 2262 | let mut positional_args = vec![]; |
| 2263 | let mut keyword_args = vec![]; |
| 2264 | let mut seen_keyword = false; |
| 2265 | |
| 2266 | loop { |
| 2267 | if self.at(Kind::RightParen) { |
| 2268 | break; |
| 2269 | } |
| 2270 | if self.at(Kind::Identifier) && matches!(self.peek_kind(), Ok(Kind::Assign)) { |
| 2271 | seen_keyword = true; |
| 2272 | let keyword_arg = self.parse_keyword_item()?; |
| 2273 | keyword_args.push(keyword_arg); |
| 2274 | } else if self.at(Kind::Mul) { |
| 2275 | let star_arg_node = self.start_node(); |
| 2276 | self.bump(Kind::Mul); |
| 2277 | let expr = self.parse_expression()?; |
| 2278 | let star_arg = Expression::Starred(Box::new(Starred { |
| 2279 | node: self.finish_node(star_arg_node), |
| 2280 | value: expr, |
| 2281 | })); |
| 2282 | positional_args.push(star_arg); |
| 2283 | } else if self.at(Kind::Pow) { |
| 2284 | let kwarg_node = self.start_node(); |
| 2285 | self.bump(Kind::Pow); |
| 2286 | seen_keyword = true; |
| 2287 | let expr = self.parse_expression()?; |
| 2288 | let kwarg = Keyword { |
| 2289 | node: self.finish_node(kwarg_node), |
| 2290 | arg: None, |
| 2291 | value: expr, |
| 2292 | }; |
| 2293 | keyword_args.push(kwarg); |
| 2294 | } else { |
| 2295 | if seen_keyword { |
| 2296 | let node_end = self.finish_node(node); |
| 2297 | panic!("Positional arguments cannot come after keyword arguments."); |
| 2298 | } |
| 2299 | let arg = self.parse_named_expression()?; |
no test coverage detected