summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordefanor <defanor@thunix.net>2024-05-26 16:19:49 +0300
committerdefanor <defanor@thunix.net>2024-05-26 16:19:49 +0300
commite7ade07eca0e157e911d8fb07a953ac05febb6fa (patch)
tree492a2ed70318d0c4943a2a907603152813c2ecf6
parentdc4d6976c09036c178bbf14762483990244243a8 (diff)
Add a Rust parser exampleHEADmaster
-rw-r--r--rust-nom/Cargo.toml10
-rw-r--r--rust-nom/example.rs47
2 files changed, 57 insertions, 0 deletions
diff --git a/rust-nom/Cargo.toml b/rust-nom/Cargo.toml
new file mode 100644
index 0000000..772dcbd
--- /dev/null
+++ b/rust-nom/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "example"
+version = "0.0.0"
+
+[dependencies]
+nom = "~7"
+
+[[bin]]
+name = "example"
+path = "example.rs"
diff --git a/rust-nom/example.rs b/rust-nom/example.rs
new file mode 100644
index 0000000..fcc9f5b
--- /dev/null
+++ b/rust-nom/example.rs
@@ -0,0 +1,47 @@
+extern crate nom;
+use std::env;
+pub use nom::{
+ IResult,
+ multi::{many0, many1},
+ branch::alt,
+ sequence::{delimited, preceded},
+ character::complete::{one_of, none_of, anychar, char}
+};
+use Node::{Tree, Literal};
+
+type Forest = Vec<Node>;
+
+#[derive(Debug)]
+enum Node {
+ Tree(Forest),
+ Literal(String),
+}
+
+fn parse_literal(input: &str) -> IResult<&str, Node> {
+ alt((many1(one_of(" \n")),
+ many1(alt((preceded(char('\\'), one_of(" \n()\\")),
+ none_of(" \n()\\"))))))
+ (input)
+ .map(|(next_input, v)|
+ (next_input, Literal(v.into_iter().collect())))
+}
+
+fn parse_tree(input: &str) -> IResult<&str, Node> {
+ delimited(char('('), parse_forest, char(')'))(input)
+ .map(|(ni, f)| (ni, Tree(f)))
+}
+
+fn parse_elem(input: &str) -> IResult<&str, Node> {
+ alt((parse_tree, parse_literal))(input)
+}
+
+fn parse_forest(input: &str) -> IResult<&str, Forest> {
+ many0(parse_elem)(input)
+}
+
+fn main() {
+ match env::args().nth(1) {
+ None => println!("Argumetns: <input>"),
+ Some(input) => println!("Result: {:?}", parse_forest(input.as_ref()))
+ }
+}