Skip to content

Commit 6b60f85

Browse files
authored
Merge pull request #7 from youknowone/lalrpop
Embed generated parser + update lalrpop
2 parents d66d935 + 39b2dbe commit 6b60f85

File tree

7 files changed

+75559
-32
lines changed

7 files changed

+75559
-32
lines changed

.github/workflows/ci.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ jobs:
3737

3838
- uses: Swatinem/rust-cache@v2
3939

40-
- name: run tests
40+
- name: run tests with embedded parser
41+
run: cargo test --all --no-default-features
42+
- name: run tests with generated parser
4143
run: cargo test --all --all-features
4244

4345
lint:

parser/Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ license = "MIT"
99
edition = "2021"
1010

1111
[features]
12-
default = ["lalrpop"] # removing this causes potential build failure
12+
default = []
1313
serde = ["dep:serde", "rustpython-compiler-core/serde"]
1414

1515
[build-dependencies]
1616
anyhow = { workspace = true }
17-
lalrpop = { version = "0.19.9", optional = true }
17+
lalrpop = { version = "0.20.0", default-features = false, optional = true }
1818
phf_codegen = "0.11.1"
1919
tiny-keccak = { version = "2", features = ["sha3"] }
2020

@@ -31,7 +31,7 @@ unicode_names2 = { workspace = true }
3131

3232
unic-emoji-char = "0.9.0"
3333
unic-ucd-ident = "0.9.0"
34-
lalrpop-util = "0.19.8"
34+
lalrpop-util = { version = "0.20.0", default-features = false }
3535
phf = "0.11.1"
3636
rustc-hash = "1.1.0"
3737
serde = { version = "1.0.133", optional = true, default-features = false, features = ["derive"] }

parser/build.rs

+30-20
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,39 @@ use std::path::{Path, PathBuf};
55
use tiny_keccak::{Hasher, Sha3};
66

77
fn main() -> anyhow::Result<()> {
8-
const SOURCE: &str = "python.lalrpop";
98
let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
9+
gen_phf(&out_dir);
1010

11+
const SOURCE: &str = "src/python.lalrpop";
1112
println!("cargo:rerun-if-changed={SOURCE}");
1213

13-
try_lalrpop(SOURCE, &out_dir.join("python.rs"))?;
14-
gen_phf(&out_dir);
14+
let target;
15+
let error;
16+
17+
#[cfg(feature = "lalrpop")]
18+
{
19+
target = out_dir.join("src/python.rs");
20+
}
21+
#[cfg(not(feature = "lalrpop"))]
22+
{
23+
target = PathBuf::from("src/python.rs");
24+
error = "python.lalrpop and src/python.rs doesn't match. This is a rustpython-parser bug. Please report it unless you are editing rustpython-parser. Run `lalrpop src/python.lalrpop` to build parser again.";
25+
}
26+
27+
let Some(message) = requires_lalrpop(SOURCE, &target) else {
28+
return Ok(());
29+
};
1530

16-
Ok(())
31+
#[cfg(feature = "lalrpop")]
32+
{
33+
let Err(e) = try_lalrpop() else {
34+
return Ok(());
35+
};
36+
error = e;
37+
}
38+
39+
println!("cargo:warning={message}");
40+
panic!("running lalrpop failed. {error:?}");
1741
}
1842

1943
fn requires_lalrpop(source: &str, target: &Path) -> Option<String> {
@@ -68,28 +92,14 @@ fn requires_lalrpop(source: &str, target: &Path) -> Option<String> {
6892
None
6993
}
7094

71-
fn try_lalrpop(source: &str, target: &Path) -> anyhow::Result<()> {
72-
let Some(_message) = requires_lalrpop(source, target) else {
73-
return Ok(());
74-
};
75-
76-
#[cfg(feature = "lalrpop")]
95+
#[cfg(feature = "lalrpop")]
96+
fn try_lalrpop() -> Result<(), Box<dyn std::error::Error>> {
7797
// We are not using lalrpop::process_root() or Configuration::process_current_dir()
7898
// because of https://github.com/lalrpop/lalrpop/issues/699.
7999
lalrpop::Configuration::new()
80100
.use_cargo_dir_conventions()
81101
.set_in_dir(Path::new("."))
82102
.process()
83-
.unwrap_or_else(|e| {
84-
println!("cargo:warning={_message}");
85-
panic!("running lalrpop failed. {e:?}");
86-
});
87-
88-
#[cfg(not(feature = "lalrpop"))]
89-
{
90-
println!("cargo:warning=try: cargo build --manifest-path=compiler/parser/Cargo.toml --features=lalrpop");
91-
}
92-
Ok(())
93103
}
94104

95105
fn sha_equal(expected_sha3_str: &str, actual_sha3: &[u8; 32]) -> bool {

parser/src/lib.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,12 @@ pub use rustpython_ast as ast;
116116

117117
mod function;
118118
// Skip flattening lexer to distinguish from full parser
119+
mod context;
119120
pub mod lexer;
120121
mod mode;
121122
mod parser;
122-
mod string;
123-
#[rustfmt::skip]
124-
mod python;
125-
mod context;
126123
mod soft_keywords;
124+
mod string;
127125
mod token;
128126

129127
pub use mode::Mode;
@@ -133,3 +131,15 @@ pub use parser::{
133131
};
134132
pub use string::FStringErrorType;
135133
pub use token::{StringKind, Tok};
134+
135+
#[rustfmt::skip]
136+
mod python {
137+
#![allow(clippy::all)]
138+
#![allow(unused)]
139+
140+
#[cfg(feature = "lalrpop")]
141+
include!(concat!(env!("OUT_DIR"), "/src/python.rs"));
142+
143+
#[cfg(not(feature = "lalrpop"))]
144+
include!("python.rs");
145+
}

parser/src/parser.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ fn parse_error_from_lalrpop(
250250
source_path,
251251
}
252252
}
253-
LalrpopError::UnrecognizedEOF { location, expected } => {
253+
LalrpopError::UnrecognizedEof { location, expected } => {
254254
// This could be an initial indentation error that we should ignore
255255
let indent_error = expected == ["Indent"];
256256
if indent_error {
File renamed without changes.

0 commit comments

Comments
 (0)