Add parsing for conditions, directions, tile kinds

This commit is contained in:
2025-05-11 20:27:04 -07:00
parent d895bd27ab
commit cd8cc1dd57
+112
View File
@@ -39,6 +39,100 @@ fn label_line() -> impl Rule {
(":", Tag("label", label_name), eol)
}
fn tile_kind() -> impl Rule {
(Opt((tile_color, ww)), tile_base_kind)
}
fn tile_color() -> impl Rule {
(
Alt(("blue", "green", "cyan", "red", "purple", "yellow", "white")),
Not('a'..='z'),
)
}
fn tile_base_kind() -> impl Rule {
let ac = (
And('a'..='c'),
Alt((
"ammo",
"bear",
"blinkwall",
"bomb",
"boulder",
"breakable",
"bullet",
"clockwise",
"counter",
)),
);
let dk = (
And('d'..='k'),
Alt((
"door",
"duplicator",
"empty",
"energizer",
"fake",
"forest",
"gem",
"head",
"invisible",
"key",
)),
);
let lr = (
And('l'..='r'),
Alt((
"line", "lion", "monitor", "normal", "object", "passage", "player", "pusher",
"ricochet", "ruffian",
)),
);
let s = (
And("s"),
Alt((
"scroll",
"segment",
"shark",
"sliderew",
"sliderns",
"slime",
"solid",
"spinninggun",
"star",
)),
);
let tz = (
And('t'..='z'),
Alt(("tiger", "torch", "transporter", "water")),
);
Alt((ac, dk, lr, s, tz))
}
fn condition() -> impl Rule {
let base = Alt((
"alligned",
("any", ww, tile_kind),
("blocked", ww, direction),
"contact",
"energized",
));
(star!("not", ww), base)
}
fn direction() -> impl Rule {
let modifier = Alt(("cw", "ccw", "rndp", "opp"));
(star!(modifier, ww), base_direction, Not('a'..='z'))
}
fn base_direction() -> impl Rule {
// Some directions are prefixes of others, which can break parsing.
// To prevent this, we roughly order the strings from longest to shortest.
let dynamic = Alt(("flow", "rndne", "rndns", "rnd", "seek"));
let long = Alt(("north", "south", "east", "west", "idle"));
let short = Alt(("n", "s", "e", "w", "i"));
(Alt((dynamic, long, short)), Not('a'..='z'))
}
fn label_name() -> impl Rule {
let namespace = (plus!(word_char), "~");
(
@@ -98,6 +192,24 @@ mod test {
parse_err(&label_name, "~foo");
}
#[test]
fn test_direction() {
parse(&direction, "n");
parse(&direction, "north");
parse(&direction, "rndp rndne");
parse(&direction, "opp seek");
parse(&direction, "cw cw cw flow");
}
#[test]
fn test_condition() {
parse(&condition, "alligned");
parse(&condition, "blocked seek");
parse(&condition, "not blocked rndp seek");
parse(&condition, "any red lion");
parse(&condition, "any bear");
}
#[test]
fn test_references() {
let mut p = Parser::new("#send foo");