1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// build.rs
use std::env;
use std::fs;
use std::path::Path;
fn generate_transitions(
symbol: &str,
states: &[&str],
next_state: &str,
) -> String {
let transitions = states
.iter()
.map(|state| {
format!(
"
((St::{symbol}, St::{state}), (St::{next_state}, St::{next_state})),"
)
})
.collect::<Vec<String>>()
.join("");
transitions
}
macro_rules! add {
($r:ident, $symbol:literal, $states:expr, $next_state:literal) => {
$r.push_str(&generate_transitions(
$symbol,
$states,
$next_state,
));
};
}
macro_rules! transitions_table {
($r:ident) => {
let all = &[
"ST", "HE", "GC", "OC", "FL", "CT", "PC", "PM", "PP",
"TC", "MS", "MP", "MX", "MI",
];
add!($r, "TC", &["ST", "HE"], "HE");
add!(
$r,
"TC",
&[
"GC", "OC", "FL", "TC", "PC", "PM", "PP", "MS", "MP",
"MX", "MI"
],
"TC"
);
add!($r, "GC", all, "GC");
add!($r, "OC", all, "OC");
add!($r, "FL", all, "FL");
add!($r, "PC", all, "PC");
add!($r, "PM", all, "PM");
add!($r, "PP", all, "PP");
add!(
$r,
"CT",
&[
"ST", "HE", "GC", "OC", "FL", "TC", "PC", "PM", "PP",
"MS", "MX"
],
"CT"
);
add!(
$r,
"MI",
&[
"ST", "HE", "GC", "OC", "FL", "CT", "TC", "PC", "PM",
"PP", "MS", "MX"
],
"MI"
);
add!($r, "MP", &["TC", "GC", "PC", "PM", "PP", "MI"], "MP");
add!($r, "MS", &["MI", "MP", "TC"], "MS");
add!($r, "MX", &["MI", "MX", "MP", "TC"], "MX");
add!(
$r,
"MC",
&["CT", "MI", "MP", "MS", "MX", "PM", "PP", "PC"],
"MC"
);
};
}
fn generate_build_transitions_function() -> String {
let mut r = String::from(
"fn build_transitions() -> Transitions {
HashMap::from([",
);
transitions_table!(r);
r.push_str(
"
])
}",
);
r
}
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path =
Path::new(&out_dir).join("poparser-transitions.rs");
fs::write(dest_path, generate_build_transitions_function())
.unwrap();
println!("cargo:rerun-if-changed=build.rs");
}
|