Commit graph

28 commits

Author SHA1 Message Date
Zsolt Dollenstein
b230302947
Fix tokenizing 0else
This is an obscure one.

`_ if 0else _` failed to parse with some very weird errors. It turns out that the tokenizer tries to parse `0else` as a single number, but when it encounters `l` it realizes it can't be a single number and it backtracks.

Unfortunately the backtracking logic was broken, and it failed to correctly backtrack one of the offsets used for whitespace parsing (the byte offset since the start of the line). This caused whitespace nodes to refer to incorrect parts of the input text, eventually resulting in the above behavior.

This PR fixes the bookkeeping when the tokenizer backtracks.

Reported in #930.
2023-05-27 19:33:20 +01:00
Zsolt Dollenstein
a5958d1531
Fix parsing of nested f-string specifiers
For an expression like `f"{one:{two:}{three}}"`, `three` is not in an f-string spec, and should be tokenized accordingly.

This PR fixes the `format_spec_count` bookkeeping in the tokenizer, so it properly decrements it when a closing `}` is encountered but only if the `}` closes a format_spec.

Reported in #930.
2023-05-27 13:00:20 +01:00
Zsolt Dollenstein
110109aee6
Allow walrus in slices
See https://github.com/python/cpython/pull/23317

Raised in #930.
2023-05-27 10:07:19 +01:00
John Litborn
ea19578293
Fix crash on escaped backslashes in rf-string (#921) 2023-05-17 15:49:40 +01:00
Steven Troxler
b5c34d39a0
Fix Github issue 855 - fail to parse with statement (#861)
* Fix Github issue 855 - fail to parse with statement

When we added support for parenthesized with statements, the
grammar on the with itself was correct (it's a right and left
parenthesis around a comma-separated list of with-items, with
a possible trailing comma).

But inside of the "as" variation of the with_item rule we have a peek at
the next character, which was allowing for a comma or a colon. That peek
needs to also accept right parentheses - otherwise, if the last item
contains an `as` and has no trailing comma we fail to parse.

The bug is exercisecd by, for example, this code snippet:
```
with (foo, bar as bar,):
    pass
```

The with_wickedness test fixture has been revised to include both
the plain and async variations of this example snippet with and without
trailing comma, and tests pass after the peek rule fix.

* Add more tests covering the plain expression form of `with_item`
2023-02-16 10:49:05 -08:00
Zsolt Dollenstein
343f56f607
[parser] bail on deeply nested expressions (#718) 2022-07-04 14:45:42 +01:00
Zsolt Dollenstein
c894160d4a
bump rust dependencies (#714) 2022-06-26 09:50:40 +01:00
Zsolt Dollenstein
9925117391
Support whitespace after ParamSlash (#713)
* add whitespace_after field to ParamSlash
* codegen
2022-06-26 09:42:37 +01:00
Zsolt Dollenstein
5592f2e00f
Fix parsing of parenthesized empty tuples (#712)
* Don't drop rpars from empty tuples during inflate
2022-06-26 09:41:49 +01:00
Zsolt Dollenstein
4c9728ab12
Tokenize escaped quotes in raw f-strings correctly (#701) 2022-06-16 09:47:57 +01:00
Zsolt Dollenstein
153c6d12c0
Only skip supported escaped characters in f-strings (#700) 2022-06-16 09:47:36 +01:00
Zsolt Dollenstein
ebe1851c2b
Add support for PEP-646 (#696) 2022-06-13 09:52:31 -06:00
Zsolt Dollenstein
380f045fe0
parser: use references instead of smart pointers for Tokens (#691)
* Add cst_node proc macro

* Split CST nodes into Deflated/Inflated versions
2022-06-07 04:08:37 -06:00
Zsolt Dollenstein
c30bbcfa48
make sure ParserError's raw_line is zero-indexed (#681) 2022-05-04 05:51:49 -06:00
Zsolt Dollenstein
fb56fa6b8f
[native] Make IntoPy conversion fallible (#639)
* Make IntoPy fallible
* Simplify test case so it works on 3.6
2022-02-07 11:52:29 +00:00
Zsolt Dollenstein
c91655fbba
fix copyright headers and add a script to check (#635) 2022-02-01 11:13:17 +00:00
Zsolt Dollenstein
8ed3a9cd5c
[native] Box most enums (#632)
* Box most enums

* add big nested expression as fixture
2022-01-28 10:33:33 +00:00
Batuhan Taskaya
2345848d4a
[native] Allow unparenthesized tuples inside f-strings (#621) 2022-01-23 09:10:47 -08:00
Batuhan Taskaya
2b2b25bb08
Don't redundantly nest StarredElement inside another Element (#624) 2022-01-23 05:45:27 -08:00
Zsolt Dollenstein
0c509b3f43
Stop indentation checking at EOF (#611) 2022-01-18 08:47:42 +00:00
Sehyo Chang
cafbfac150
change pyo3 as optional dependency in native Python Parser (#598) 2022-01-16 18:46:54 +00:00
Steven Troxler
1337022770
[WIP] Support Parenthesized With Statements (#584)
On the python side, we can add parentheses from MaybeSentinel.DEFAULT if the whitespace requires it.

On the rust side, we support the new grammar but codegen will only add explicitly included parentheses for now - it should be possible to match python behavior but it's not urgent so I've left a TODO
2022-01-07 12:21:58 -08:00
Steven Troxler
2f75246c3a
Fix variable name in lambda (#590) 2022-01-07 09:29:51 +00:00
Zsolt Dollenstein
86431eea89
Make sure dedents are emitted for inputs without trailing newlines (#573) 2022-01-04 20:04:21 +00:00
Zsolt Dollenstein
9932a6d339
Implement PEP-634 - Match statement (#568)
* ParenthesizedNode implementation for Box

* match statement rust CST and grammar

* match statement python CST and docs

* run rust unit tests in release mode for now
2021-12-30 10:00:51 +00:00
Zsolt Dollenstein
67db03915d
implement PEP-654: except* (#571) 2021-12-29 21:23:46 +00:00
Zsolt Dollenstein
c44ff0500b
Fix license headers (#560)
* Facebook -> Meta

* remove year from doc copyright
2021-12-28 11:55:18 +00:00
Zsolt Dollenstein
c02de9b718
Implement a Python PEG parser in Rust (#566)
This massive PR implements an alternative Python parser that will allow LibCST to parse Python 3.10's new grammar features. The parser is implemented in Rust, but it's turned off by default through the `LIBCST_PARSER_TYPE` environment variable. Set it to `native` to enable. The PR also enables new CI steps that test just the Rust parser, as well as steps that produce binary wheels for a variety of CPython versions and platforms.

Note: this PR aims to be roughly feature-equivalent to the main branch, so it doesn't include new 3.10 syntax features. That will be addressed as a follow-up PR.

The new parser is implemented in the `native/` directory, and is organized into two rust crates: `libcst_derive` contains some macros to facilitate various features of CST nodes, and `libcst` contains the `parser` itself (including the Python grammar), a `tokenizer` implementation by @bgw, and a very basic representation of CST `nodes`. Parsing is done by
1. **tokenizing** the input utf-8 string (bytes are not supported at the Rust layer, they are converted to utf-8 strings by the python wrapper)
2. running the **PEG parser** on the tokenized input, which also captures certain anchor tokens in the resulting syntax tree
3. using the anchor tokens to **inflate** the syntax tree into a proper CST

Co-authored-by: Benjamin Woodruff <github@benjam.info>
2021-12-21 18:14:39 +00:00