Write initial code for parsing stats into chunks
This commit is contained in:
Generated
+42
@@ -14,12 +14,28 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"codepage-437",
|
"codepage-437",
|
||||||
|
"compact_str",
|
||||||
"insta",
|
"insta",
|
||||||
"nom",
|
"nom",
|
||||||
"peg_macro",
|
"peg_macro",
|
||||||
"pest",
|
"pest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "castaway"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5"
|
||||||
|
dependencies = [
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codepage-437"
|
name = "codepage-437"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -29,6 +45,20 @@ dependencies = [
|
|||||||
"csv",
|
"csv",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "compact_str"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a"
|
||||||
|
dependencies = [
|
||||||
|
"castaway",
|
||||||
|
"cfg-if",
|
||||||
|
"itoa",
|
||||||
|
"rustversion",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "console"
|
||||||
version = "0.15.11"
|
version = "0.15.11"
|
||||||
@@ -201,6 +231,12 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
@@ -233,6 +269,12 @@ version = "2.7.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.101"
|
version = "2.0.101"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ peg_macro = { path = "./peg_macro"}
|
|||||||
insta = "1.39.0"
|
insta = "1.39.0"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
pest = "2.7.15"
|
pest = "2.7.15"
|
||||||
|
compact_str = "0.9.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = "1.39.0"
|
insta = "1.39.0"
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
pub mod labels;
|
pub mod parse;
|
||||||
|
|||||||
@@ -1,4 +1,85 @@
|
|||||||
use crate::{peg::ParseState, world::Stat};
|
use std::ops::Range;
|
||||||
|
|
||||||
|
use compact_str::CompactString;
|
||||||
|
use grammar::Tag;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
peg::{Capture, ParseState},
|
||||||
|
world::Stat,
|
||||||
|
};
|
||||||
|
|
||||||
|
type ParsedStat = Vec<Chunk>;
|
||||||
|
enum Chunk {
|
||||||
|
Verbatim(String),
|
||||||
|
Label(LabelName),
|
||||||
|
Reference(LabelName),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LabelName {
|
||||||
|
namespace: CompactString,
|
||||||
|
name: CompactString,
|
||||||
|
local: Option<CompactString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_stat_labels(stat: &Stat) -> ParsedStat {
|
||||||
|
let code = &stat.code;
|
||||||
|
let mut parser = ParseState::new(code);
|
||||||
|
assert!(
|
||||||
|
grammar::program(&mut parser),
|
||||||
|
"Couldn't parse code: {:?}",
|
||||||
|
code
|
||||||
|
);
|
||||||
|
|
||||||
|
// Split code along capture group boundaries
|
||||||
|
let mut result = vec![];
|
||||||
|
let mut offset = 0;
|
||||||
|
|
||||||
|
let mut push_label = |cap: Capture<_>| {
|
||||||
|
let Range { start, end } = cap.span();
|
||||||
|
if offset < start {
|
||||||
|
result.push(Chunk::Verbatim(code[offset..start].into()))
|
||||||
|
}
|
||||||
|
let mut label = LabelName {
|
||||||
|
namespace: CompactString::with_capacity(0),
|
||||||
|
name: CompactString::with_capacity(0),
|
||||||
|
local: None,
|
||||||
|
};
|
||||||
|
for child in cap.children() {
|
||||||
|
match child.kind() {
|
||||||
|
Tag::Namespace => {
|
||||||
|
label.namespace = child.text().into();
|
||||||
|
}
|
||||||
|
Tag::Global => {
|
||||||
|
label.name = child.text().into();
|
||||||
|
}
|
||||||
|
Tag::Local => label.local = Some(child.text().into()),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push(Chunk::Label(label));
|
||||||
|
offset = end;
|
||||||
|
};
|
||||||
|
|
||||||
|
for cap in parser.captures() {
|
||||||
|
match cap.kind() {
|
||||||
|
Tag::Label => {
|
||||||
|
push_label(cap);
|
||||||
|
}
|
||||||
|
Tag::Reference => {
|
||||||
|
for child in cap.children() {
|
||||||
|
if child.kind() == Tag::Label {
|
||||||
|
push_label(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if offset < code.len() {
|
||||||
|
result.push(Chunk::Verbatim(code[offset..code.len()].into()));
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_labels(b: &Stat) {
|
pub fn print_labels(b: &Stat) {
|
||||||
let code = &b.code;
|
let code = &b.code;
|
||||||
@@ -10,7 +91,7 @@ pub fn print_labels(b: &Stat) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for capture in parser.captures() {
|
for capture in parser.captures() {
|
||||||
if capture.kind() == grammar::Tag::Label {
|
if capture.kind() == Tag::Label {
|
||||||
println!("- {}", capture.text());
|
println!("- {}", capture.text());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,7 +187,7 @@ mod grammar {
|
|||||||
"n" / "s" / "e" / "w" / "i" // short forms
|
"n" / "s" / "e" / "w" / "i" // short forms
|
||||||
) eow;
|
) eow;
|
||||||
|
|
||||||
// Labels (defined locations in the code)
|
// Labels
|
||||||
// Examples: foo, namespace~foo, foo.local, .local, @
|
// Examples: foo, namespace~foo, foo.local, .local, @
|
||||||
label = #Label:(namespace? (label_name / #Anon:"@"));
|
label = #Label:(namespace? (label_name / #Anon:"@"));
|
||||||
namespace = #Namespace:label_word "~";
|
namespace = #Namespace:label_word "~";
|
||||||
@@ -115,9 +196,9 @@ mod grammar {
|
|||||||
label_local = "." #Local:label_word;
|
label_local = "." #Local:label_word;
|
||||||
label_word = word_char+; // labels can start with 0-9
|
label_word = word_char+; // labels can start with 0-9
|
||||||
|
|
||||||
// Messages (references to labels)
|
// References to labels
|
||||||
// Examples: foo, all:namespace~bar.baz, @b, @f
|
// Examples: foo, all:namespace~bar.baz, @b, @f
|
||||||
message = #Message:(recipient? message_name);
|
message = #Reference:(recipient? #Label:message_name);
|
||||||
recipient = #Recipient:word ":";
|
recipient = #Recipient:word ":";
|
||||||
message_name = namespace? (label_name / #Anon:anon_message);
|
message_name = namespace? (label_name / #Anon:anon_message);
|
||||||
anon_message = "@" ("b" / "f");
|
anon_message = "@" ("b" / "f");
|
||||||
@@ -216,7 +297,7 @@ mod test {
|
|||||||
let before = &input[last_index..group.span().start];
|
let before = &input[last_index..group.span().start];
|
||||||
let inner = match group.kind() {
|
let inner = match group.kind() {
|
||||||
Tag::Label => format!("({})", group.text()),
|
Tag::Label => format!("({})", group.text()),
|
||||||
Tag::Message => format!("[{}]", group.text()),
|
Tag::Reference => format!("[{}]", group.text()),
|
||||||
_ => group.text().into(),
|
_ => group.text().into(),
|
||||||
};
|
};
|
||||||
result.push_str(before);
|
result.push_str(before);
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: src/labels/labels.rs
|
source: src/labels/parse.rs
|
||||||
expression: result
|
expression: result
|
||||||
---
|
---
|
||||||
'
|
'
|
||||||
+1
-1
@@ -5,7 +5,7 @@ mod preprocess;
|
|||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use labels::labels::print_labels;
|
use labels::parse::print_labels;
|
||||||
use preprocess::eval::Context;
|
use preprocess::eval::Context;
|
||||||
use std::{env, error::Error, fs, path::PathBuf, process::exit};
|
use std::{env, error::Error, fs, path::PathBuf, process::exit};
|
||||||
use world::World;
|
use world::World;
|
||||||
|
|||||||
Reference in New Issue
Block a user