Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser rewrite #274

Merged
merged 156 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
7464a02
Start work on eliminating code and moving stuff out
Kampfkarren Apr 2, 2023
086f247
Tests compile
Kampfkarren Apr 2, 2023
83b69e9
Initial tokenizer to pass anonymous-functions-1
Kampfkarren Apr 3, 2023
97e4666
Saner APIs
Kampfkarren Apr 3, 2023
6710796
Decent parsing, TokenReference
Kampfkarren Apr 4, 2023
1b0c946
Start work on expressions (I need to merge)
Kampfkarren Apr 4, 2023
3c0c51c
anonymous-functions-1 passes
Kampfkarren Apr 5, 2023
87bd000
anonymous-functions-2 passing
Kampfkarren Apr 5, 2023
672d3bd
anonymous-functions-3 pass
Kampfkarren Apr 5, 2023
2e20295
anonymous-functions-4
Kampfkarren Apr 5, 2023
e3a5b3e
assignment-1
Kampfkarren Apr 5, 2023
6268bfe
assignment-2
Kampfkarren Apr 5, 2023
ed63d2a
assignment-3 mini boss
Kampfkarren Apr 5, 2023
3825f2e
binops (call-1 and call-2 just worked)
Kampfkarren Apr 5, 2023
c79ea97
do, empty
Kampfkarren Apr 5, 2023
cd8b08e
exponents
Kampfkarren Apr 5, 2023
2df64c0
fractional-numbers
Kampfkarren Apr 5, 2023
1bf2c90
function-declaration-1
Kampfkarren Apr 5, 2023
788e687
function-declaration-2
Kampfkarren Apr 6, 2023
9ff34b9
function-shortcuts
Kampfkarren Apr 6, 2023
bc2dbef
generic-for-loop-1, free: generic-for-loop-2, goto-as-identifier, gt-…
Kampfkarren Apr 7, 2023
d77eec0
if-1, and a bunch of free ones
Kampfkarren Apr 7, 2023
cba1b4d
local-function-1 (2 for free)
Kampfkarren Apr 7, 2023
b62e651
multi-line-comments-1 through 4
Kampfkarren Apr 7, 2023
a82c45f
5 and 6
Kampfkarren Apr 7, 2023
cbdd8f5
7, 8, 9
Kampfkarren Apr 7, 2023
d4adf09
multi-line-string 1-5
Kampfkarren Apr 7, 2023
ae6fd70
Multi-line-strings, negative numbers
Kampfkarren Apr 7, 2023
ba4689e
Numeric for loop
Kampfkarren Apr 7, 2023
09bfddd
Paren expressions
Kampfkarren Apr 7, 2023
fb830f6
repeat-until
Kampfkarren Apr 7, 2023
07dfe39
return-break
Kampfkarren Apr 7, 2023
3da5e9d
semicolons-1, semicolons-2
Kampfkarren Apr 7, 2023
5dd8698
Shebangs, but I changed the behavior to make sense
Kampfkarren Apr 7, 2023
26a4d81
single-line-comment-4 to 5
Kampfkarren Apr 7, 2023
5662b80
Fix bug with character counts
Kampfkarren Apr 7, 2023
a026a1e
A lot
Kampfkarren Apr 7, 2023
46d5ec8
unops, utf-8 for free
Kampfkarren Apr 9, 2023
3d4bf88
while loops
Kampfkarren Apr 9, 2023
10b3769
Fix some regressions when parsing Zombie Strike
Kampfkarren Apr 9, 2023
d925b08
Hexadecimals
Kampfkarren Apr 9, 2023
fc8697f
Better APIs
Kampfkarren Apr 9, 2023
0626512
TokenReference::symbol
Kampfkarren Apr 9, 2023
a9ca905
Start work on fail cases
Kampfkarren Apr 9, 2023
c641526
Keep parsing blocks with unexpected token
Kampfkarren Apr 9, 2023
19cd8db
Some cargo insta test up to a point
Kampfkarren Apr 9, 2023
e967180
I'm ok with these
Kampfkarren Apr 9, 2023
194a145
Up to do-1
Kampfkarren Apr 9, 2023
a7e212d
Every result so far is fine
Kampfkarren Apr 9, 2023
ff19bdb
Start work on more specific function argument parsing
Kampfkarren Apr 10, 2023
c5b378b
Snaps after fixing a panic
Kampfkarren Apr 10, 2023
d76e5e4
Some more passes
Kampfkarren Apr 10, 2023
34004c7
Everything is Okay
Kampfkarren Apr 10, 2023
d5642f9
Some more snaps
Kampfkarren Apr 10, 2023
702ce8f
Some more snaps
Kampfkarren Apr 10, 2023
5847c25
Everything's fine
Kampfkarren Apr 10, 2023
8439276
We can parse every fail case now?
Kampfkarren Apr 10, 2023
a9bbbb9
It's fine
Kampfkarren Apr 10, 2023
2c9e872
Reduce errors until the next stmt
Kampfkarren Apr 10, 2023
4755639
Support recovered tokens
Kampfkarren Apr 10, 2023
6b65557
Remove errors, to be replaced
Kampfkarren Apr 10, 2023
b430b76
Start work on recovered tokens
Kampfkarren Apr 10, 2023
3902515
Unclosed comments
Kampfkarren Apr 11, 2023
fa6a63b
Shebang is weird, but the rest of these are nice
Kampfkarren Apr 11, 2023
c9e6810
Rewrite todo
Kampfkarren Apr 11, 2023
6bd26f3
Initial fuzzers
Kampfkarren Apr 11, 2023
e3ec709
Start cleanup of current().unwrap()
Kampfkarren Apr 11, 2023
bcdebbc
Clean up all BAD uses of current().unwrap()
Kampfkarren Apr 11, 2023
a377528
Quick clippy
Kampfkarren Apr 11, 2023
5655952
Bad numbers
Kampfkarren Apr 11, 2023
090dd38
Fix multiple decimals
Kampfkarren Apr 11, 2023
b02f113
Error with invalid 0x
Kampfkarren Apr 11, 2023
18735cc
This came up with fuzzing
Kampfkarren Apr 11, 2023
e5d03f6
I think this is also an error case
Kampfkarren Apr 11, 2023
06572d3
push_punctuated
Kampfkarren Apr 11, 2023
a4d1b0e
clippy
Kampfkarren Apr 11, 2023
9aadc94
Remove outdated todo
Kampfkarren Apr 11, 2023
d1683be
Update benchmarks
Kampfkarren Apr 11, 2023
c95ca22
Remove todo
Kampfkarren Apr 11, 2023
4a20a9b
Add recovery test, but I want to add coverage testing
Kampfkarren Apr 11, 2023
87f6816
Sanity assert
Kampfkarren Apr 12, 2023
bcfe3fc
Cool, it just works
Kampfkarren Apr 12, 2023
8b7d16c
This doesn't need to use a macro
Kampfkarren Apr 12, 2023
df82b0d
Remove UnOp::precedence
Kampfkarren Apr 12, 2023
bdb522b
Clean up BinOp
Kampfkarren Apr 12, 2023
3cb9410
We didn't
Kampfkarren Apr 12, 2023
c48a306
We changed this
Kampfkarren Apr 12, 2023
3cc6cd1
I can't get this to repro anyway
Kampfkarren Apr 12, 2023
4b47711
New range
Kampfkarren Apr 12, 2023
d0905de
Update ranges (but I didn't really look at them =/)
Kampfkarren Apr 12, 2023
8fab086
Test Recovered coverage
Kampfkarren Apr 12, 2023
beb8f41
Add optional range
Kampfkarren Apr 13, 2023
fb46da3
Add range field
Kampfkarren Apr 13, 2023
75423b9
Start with ranges
Kampfkarren Apr 13, 2023
b9a7bd5
Error displays as part of test
Kampfkarren Apr 13, 2023
a6a81d4
Better error message
Kampfkarren Apr 13, 2023
c1406a3
Better error messages for blocks
Kampfkarren Apr 13, 2023
1ab3909
Better table key errors
Kampfkarren Apr 16, 2023
e5fa0e4
Change parse signature
Kampfkarren Apr 16, 2023
4d1148d
Some fixes with new result type, some last stmt test. I don't love it
Kampfkarren Apr 16, 2023
ccec566
Use new helper
Kampfkarren Apr 16, 2023
eb14dab
Clean some todos
Kampfkarren Apr 16, 2023
6d69027
Remove unused
Kampfkarren Apr 16, 2023
2001be3
It doesn't
Kampfkarren Apr 16, 2023
6951dca
I think it's fine
Kampfkarren Apr 16, 2023
a45f992
Better expect_local_assignment structure
Kampfkarren Apr 16, 2023
d85d40d
Add LuaVersion field
Kampfkarren Apr 17, 2023
53be460
Luau behind feature flag is almost certainly better
Kampfkarren Apr 17, 2023
aefbf85
Make ParserState a bitfield
Kampfkarren Apr 17, 2023
949d2f7
Fix tests
Kampfkarren Apr 17, 2023
35880b3
Fix doc tests
Kampfkarren Apr 17, 2023
2ed8b94
Start work on Lua 5.2 parsing (none of these are right)
Kampfkarren Apr 22, 2023
e1a38a0
Symbol macro
Kampfkarren Apr 22, 2023
cded960
Allow unused in the symbol macro
Kampfkarren Apr 22, 2023
4aac101
goto
Kampfkarren Apr 22, 2023
ff0c0da
Numbers, working on the other stuff
Kampfkarren Apr 23, 2023
c43ece9
Z escaping
Kampfkarren Apr 23, 2023
33a64c6
Lua 5.3
Kampfkarren Apr 24, 2023
0e42181
Add Symbol::from_str test
Kampfkarren Apr 26, 2023
913e572
Fix parsing not using the correct version in tests
Kampfkarren Apr 26, 2023
0aeb645
Lua 5.4
Kampfkarren Apr 26, 2023
b953111
Fix 5.1 compile
Kampfkarren Apr 26, 2023
d42cfb5
Fix doctest without 5.1 feature
Kampfkarren Apr 26, 2023
4132187
Clean version checking macro
Kampfkarren Apr 26, 2023
712dc36
Add Lua 5.4 to default set, and I can't think of anything
Kampfkarren Apr 26, 2023
589901b
Restore ast tests
Kampfkarren Apr 26, 2023
ba5f364
Flatten AstError, since the other variants are no longer reachable
Kampfkarren Apr 26, 2023
0325eeb
Remove optional for additional
Kampfkarren Apr 26, 2023
2e6b06c
Some trivial changelogs
Kampfkarren Apr 26, 2023
bb511ea
Less trivial changelogs
Kampfkarren Apr 26, 2023
1f61ef5
parse_fallible documentation
Kampfkarren Apr 26, 2023
b4cc4ad
Handle spaces with newline whitespace position correctly
JohnnyMorganz Oct 15, 2023
544f464
Luau Parser rewrite (#276)
JohnnyMorganz Jan 7, 2024
52e61f4
Merge branch 'main' of https://github.com/Kampfkarren/full-moon into …
JohnnyMorganz Jan 7, 2024
c9cd219
Support Luau floor division + assignment (`//` and `//=`)
JohnnyMorganz Jan 7, 2024
969c448
luau: consider trivia when testing string interpolation double brace …
JohnnyMorganz Jan 7, 2024
b66b9c0
luau: support \z escape in strings (#287)
JohnnyMorganz Jan 7, 2024
7b25ffb
fix some clippy lints
JohnnyMorganz Jan 7, 2024
624d867
rename `feature = "roblox"` -> `feature = "luau"`
JohnnyMorganz Jan 7, 2024
d50a8da
Switch `multi_line` from `Option<usize>` to `usize` (#294)
JohnnyMorganz Jan 20, 2024
a83708c
CHANGELOG
Kampfkarren Jan 20, 2024
158c6cf
More changelog fixing
Kampfkarren Jan 20, 2024
0a0b6a9
Add changelog about comments
Kampfkarren Jan 20, 2024
6085060
Rename parse_ to expect_
Kampfkarren Jan 20, 2024
035a2e6
Make these not public
Kampfkarren Jan 20, 2024
29ed525
Remove UnexpectedShebang
Kampfkarren Jan 20, 2024
e409e19
InvalidNumber documentation
Kampfkarren Jan 20, 2024
734214b
I don't really have time to test this
Kampfkarren Jan 20, 2024
7405e83
This is fine
Kampfkarren Jan 20, 2024
e60bc5a
This is very rarely hit, and there's bigger problems here
Kampfkarren Jan 20, 2024
bbc1545
Too niche, not worth it
Kampfkarren Jan 20, 2024
9fa7819
I think this was implemented by Johnny
Kampfkarren Jan 20, 2024
6a12257
Sure
Kampfkarren Jan 20, 2024
2d13175
Docs
Kampfkarren Jan 20, 2024
838461b
Fix clippy with no features
Kampfkarren Jan 20, 2024
df8a981
Only have doc comment with lua 5.2
Kampfkarren Jan 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
68 changes: 34 additions & 34 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,43 @@ name: Test full-moon
on:
push:
branches:
- main
- main
pull_request:
branches:
- main
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Test (default features)
run: |
cd full-moon
cargo test
- name: Test (roblox feature)
run: |
cd full-moon
cargo test --features roblox
- name: Test (Lua 5.2 feature)
run: |
cd full-moon
cargo test --features lua52
- name: Test (Lua 5.3 feature)
run: |
cd full-moon
cargo test --features lua53
- name: Test (Lua 5.4 feature)
run: |
cd full-moon
cargo test --features lua54
- name: Test (all features)
run: |
cd full-moon
cargo test --features roblox,lua52,lua53,lua54
- name: Test (no default features)
run: |
cd full-moon
cargo test --no-default-features --features serde
- name: Rustfmt
run: |
cargo fmt -- --check
- uses: actions/checkout@v3
- name: Test (default features)
run: |
cd full-moon
cargo test
- name: Test (Luau feature)
run: |
cd full-moon
cargo test --features luau
- name: Test (Lua 5.2 feature)
run: |
cd full-moon
cargo test --features lua52
- name: Test (Lua 5.3 feature)
run: |
cd full-moon
cargo test --features lua53
- name: Test (Lua 5.4 feature)
run: |
cd full-moon
cargo test --features lua54
- name: Test (all features)
run: |
cd full-moon
cargo test --features luau,lua52,lua53,lua54
- name: Test (no default features)
run: |
cd full-moon
cargo test --no-default-features --features serde
- name: Rustfmt
run: |
cargo fmt -- --check
6 changes: 2 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{
"rust-analyzer.cargo.features": [
"roblox"
],
}
"rust-analyzer.cargo.features": ["luau", "lua52", "lua53", "lua54"]
}
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased
### Added
- **full-moon now has the ability to return multiple errors.** Added `parse_fallible`, which will return a struct containing the best possible AST, and a vector of errors. Read the documentation for guarantees on the partial AST.
- The Lua version used to parse is no longer strictly based on features set, and can now be configured precisely using `LuaVersion`. `LuaVersion` is a bitfield that can attempt to parse multiple versions of Lua at once, or be used to pin down a specific version. `parse` will use the most completely available set possible (`LuaVersion::new()`), but `parse_fallible` accepts a `LuaVersion`.
- Added support for parsing Luau's floor division assignment `//=`
- Added `TokenizerErrorType::InvalidNumber` when a number fails to parse.

### Changed
- **[BREAKING CHANGE]** `parse` now returns a vector of errors.
- **[BREAKING CHANGE]** `TokenType::StringLiteral::multi_line` has been replaced with `TokenType::StringLiteral::multi_line_depth`. It serves the same purpose except instead of being an `Option<usize>`, it is now a standard `usize`. It is advised to simply check `quote_type == StringLiteralQuoteType::Brackets` to get the previous behavior.
- **[BREAKING CHANGE]** Flattened `AstError` into just what used to be `AstError::UnexpectedToken`.
- **[BREAKING CHANGE]** `Symbol::PlusEqual` and friends are now only available when using Luau.
- Shebangs provide their trailing trivia more accurately to the rest of full-moon.
- Attempting to display `StringLiteralQuoteType::Brackets` now returns an error rather than being marked as unreachable.
- Significantly optimized the entire codebase, helping both time to parse and wasting less stack, especially in debug mode.
- `Punctuated<T>` now implements `Default` for all `T`, rather than if `T: Default`.

### Removed
- Removed `UnOp::precedence`, as unary operators do not traditionally use precedence in the same way binary operators do.
- Removed `TokenizerErrorType::UnexpectedShebang`.
- Removed `stacker` feature flag, as rewrites to the parser should make it unnecessary.

### Fixed
- Fixed comments with Unicode characters having positions that report their `character` as bytes.

## [0.19.0] - 2023-11-10
### Added
Expand Down
14 changes: 3 additions & 11 deletions benches/date.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{criterion_group, criterion_main, Criterion};
use full_moon::node::Node;

const DATE_SOURCE: &str = include_str!("./date.lua");

fn tokenize(criterion: &mut Criterion) {
criterion.bench_function("tokenize date", |b| {
b.iter(|| full_moon::tokenizer::tokens(black_box(DATE_SOURCE)))
});
}

fn parse(criterion: &mut Criterion) {
let tokens = full_moon::tokenizer::tokens(DATE_SOURCE).unwrap();

criterion.bench_function("get ast from parsed date", move |b| {
b.iter(|| full_moon::ast::Ast::from_tokens(black_box(tokens.clone())))
b.iter(|| full_moon::parse(DATE_SOURCE))
});
}

Expand All @@ -28,7 +20,7 @@ fn range(criterion: &mut Criterion) {
criterion_group! {
name = benches;
config = Criterion::default().sample_size(20);
targets = tokenize, parse, range
targets = parse, range
}

criterion_main!(benches);
14 changes: 3 additions & 11 deletions benches/t.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use criterion::{criterion_group, criterion_main, Criterion};
use full_moon::node::Node;

const T_SOURCE: &str = include_str!("./t.lua");

fn tokenize(criterion: &mut Criterion) {
criterion.bench_function("tokenize t", |b| {
b.iter(|| full_moon::tokenizer::tokens(black_box(T_SOURCE)))
});
}

fn parse(criterion: &mut Criterion) {
let tokens = full_moon::tokenizer::tokens(T_SOURCE).unwrap();

criterion.bench_function("get ast from parsed t", move |b| {
b.iter(|| full_moon::ast::Ast::from_tokens(black_box(tokens.clone())))
b.iter(|| full_moon::parse(T_SOURCE))
});
}

Expand All @@ -28,7 +20,7 @@ fn range(criterion: &mut Criterion) {
criterion_group! {
name = benches;
config = Criterion::default().sample_size(20);
targets = tokenize, parse, range
targets = parse, range
}

criterion_main!(benches);
12 changes: 7 additions & 5 deletions full-moon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ keywords = ["lua", "parser", "lua51", "lua52", "luau"]
edition = "2021"

[package.metadata.docs.rs]
# Build Locally: RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features roblox,lua52,lua53,lua54 --no-deps --open
features = ["roblox", "lua52", "lua53", "lua54"]
# Build Locally: RUSTDOCFLAGS="--cfg doc_cfg" cargo +nightly doc --features luau,lua52,lua53,lua54 --no-deps --open
features = ["luau", "lua52", "lua53", "lua54"]
rustdoc-args = ["--cfg", "doc_cfg"]

[features]
default = ["serde"]
roblox = []
luau = ["roblox"]
roblox = ["luau"] # backwards compatibility
lua52 = []
lua53 = ["lua52"]
lua54 = ["lua53"]
Expand All @@ -28,16 +29,17 @@ bytecount = "0.6"
cfg-if = "1.0"
derive_more = "0.99"
full_moon_derive = { path = "../full-moon-derive", version = "=0.11.0" }
logos = "0.12.1"
paste = "1.0"
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
smol_str = { version = "0.1.23", features = ["serde"] }
stacker = { version = "0.1.15", optional = true }

[dev-dependencies]
codespan = "0.11.1"
codespan-reporting = "0.11.1"
criterion = "0.5.1"
insta = { version = "1.26.0", features = ["glob", "yaml"] }
pretty_assertions = "1.3.0"
termcolor = "1.2.0"

[[bench]]
name = "date"
Expand Down
4 changes: 4 additions & 0 deletions full-moon/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
corpus
artifacts
coverage
36 changes: 36 additions & 0 deletions full-moon/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "full_moon_fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
libfuzzer-sys = "0.4"
old_full_moon = { package = "full_moon", version = "0.18.1", features = [
"stacker",
] }

[dependencies.full_moon]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[profile.release]
debug = 1

[[bin]]
name = "parse"
path = "fuzz_targets/parse.rs"
test = false
doc = false

[[bin]]
name = "parse_parity"
path = "fuzz_targets/parse_parity.rs"
test = false
doc = false
9 changes: 9 additions & 0 deletions full-moon/fuzz/fuzz_targets/parse.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#![no_main]

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
if let Ok(string) = std::str::from_utf8(data) {
full_moon::parse_fallible(string, full_moon::LuaVersion::new());
}
});
11 changes: 11 additions & 0 deletions full-moon/fuzz/fuzz_targets/parse_parity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![no_main]

use libfuzzer_sys::fuzz_target;

fuzz_target!(|data: &[u8]| {
if let Ok(string) = std::str::from_utf8(data) {
if old_full_moon::parse(string).is_ok() {
full_moon::parse_fallible(string, full_moon::LuaVersion::new());
}
}
});
Loading