Skip to content

Commit 23bb966

Browse files
authored
Merge pull request RustPython#3689 from coolreader18/lalrpop-from-build
Try to invoke lalrpop from parser build script
2 parents fbf45e1 + 2b0798a commit 23bb966

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed

parser/build.rs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
use std::fmt::Write as _;
22
use std::fs::File;
3-
use std::io::{BufRead, BufReader, BufWriter, Write};
3+
use std::io::{self, BufRead, BufReader, BufWriter, Write};
44
use std::path::PathBuf;
5+
use std::process::{self, Command};
56
use tiny_keccak::{Hasher, Sha3};
67

78
fn main() {
8-
check_lalrpop();
9+
check_lalrpop("src/python.lalrpop", "src/python.rs");
910
gen_phf();
1011
}
1112

12-
fn check_lalrpop() {
13-
println!("cargo:rerun-if-changed=src/python.lalrpop");
14-
let sha3_line = BufReader::with_capacity(128, File::open("src/python.rs").unwrap())
13+
fn check_lalrpop(source: &str, generated: &str) {
14+
println!("cargo:rerun-if-changed={source}");
15+
16+
let sha_prefix = "// sha3: ";
17+
let sha3_line = BufReader::with_capacity(128, File::open(generated).unwrap())
1518
.lines()
16-
.nth(1)
17-
.unwrap()
18-
.unwrap();
19-
let expected_sha3_str = sha3_line.strip_prefix("// sha3: ").unwrap();
19+
.find_map(|line| {
20+
let line = line.unwrap();
21+
line.starts_with(sha_prefix).then(|| line)
22+
})
23+
.expect("no sha3 line?");
24+
let expected_sha3_str = sha3_line.strip_prefix(sha_prefix).unwrap();
2025

2126
let actual_sha3 = {
2227
let mut hasher = Sha3::v256();
23-
let mut f = BufReader::new(File::open("src/python.lalrpop").unwrap());
28+
let mut f = BufReader::new(File::open(source).unwrap());
2429
let mut line = String::new();
2530
while f.read_line(&mut line).unwrap() != 0 {
2631
if line.ends_with('\n') {
@@ -38,24 +43,40 @@ fn check_lalrpop() {
3843
hash
3944
};
4045

46+
if sha_equal(expected_sha3_str, &actual_sha3) {
47+
return;
48+
}
49+
match Command::new("lalrpop").arg(source).status() {
50+
Ok(stat) if stat.success() => {}
51+
Ok(stat) => {
52+
eprintln!("failed to execute lalrpop; exited with {stat}");
53+
process::exit(stat.code().unwrap_or(1));
54+
}
55+
Err(e) if e.kind() == io::ErrorKind::NotFound => {
56+
eprintln!(
57+
"the lalrpop executable is not installed and parser/{source} has been changed"
58+
);
59+
eprintln!("please install lalrpop with `cargo install lalrpop`");
60+
process::exit(1);
61+
}
62+
Err(e) => panic!("io error {e:#}"),
63+
}
64+
}
65+
66+
fn sha_equal(expected_sha3_str: &str, actual_sha3: &[u8; 32]) -> bool {
4167
// stupid stupid stupid hack. lalrpop outputs each byte as "{:x}" instead of "{:02x}"
42-
let sha3_equal = if expected_sha3_str.len() == 64 {
68+
if expected_sha3_str.len() == 64 {
4369
let mut expected_sha3 = [0u8; 32];
4470
for (i, b) in expected_sha3.iter_mut().enumerate() {
4571
*b = u8::from_str_radix(&expected_sha3_str[i * 2..][..2], 16).unwrap();
4672
}
47-
actual_sha3 == expected_sha3
73+
*actual_sha3 == expected_sha3
4874
} else {
4975
let mut actual_sha3_str = String::new();
5076
for byte in actual_sha3 {
5177
write!(actual_sha3_str, "{byte:x}").unwrap();
5278
}
5379
actual_sha3_str == expected_sha3_str
54-
};
55-
56-
if !sha3_equal {
57-
eprintln!("you need to recompile lalrpop!");
58-
std::process::exit(1);
5980
}
6081
}
6182

parser/regen_lalrpop.sh

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)