From e06b20b6040f4e59170d6a7b731565eaef2ea373 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Tue, 27 Dec 2022 00:01:42 +0100 Subject: [PATCH] Fold graph::Graph into gg::Graph, add TokenKind::End to lexer --- rust/src/gg.rs | 39 ++++++++++++++++++++++---- rust/src/gg/gg.bnf | 38 +++++++++++++++---------- rust/src/gg/lexer.rs | 50 +++++++++++++++++++++++---------- rust/src/graph.rs | 66 -------------------------------------------- rust/src/lib.rs | 1 - rust/src/main.rs | 20 -------------- 6 files changed, 92 insertions(+), 122 deletions(-) delete mode 100644 rust/src/graph.rs diff --git a/rust/src/gg.rs b/rust/src/gg.rs index 2b39b1d..110e124 100644 --- a/rust/src/gg.rs +++ b/rust/src/gg.rs @@ -1,10 +1,39 @@ +use std::hash::Hash; +use im_rc::{HashSet}; + pub mod lexer; -use super::graph::Graph; +#[derive(Clone, Eq, Hash, PartialEq)] +pub struct OpenEdge(Value, Value); // edge, src -#[derive(Clone, Eq, Hash, PartialEq, Debug)] -pub enum Value<'a>{ - Name(&'a str), +#[derive(Clone, Eq, Hash, PartialEq)] +pub enum Value{ + Name(String), Number(i64), - Graph(&'a Graph, Value<'a>>), + Tuple(Vec), + Graph(Graph), +} + +#[derive(Clone, Eq, Hash, PartialEq)] +struct Edge { + dst_val: V, + src_val: V, +} + +#[derive(Clone, Eq, Hash, PartialEq)] +pub struct Graph { + edges: HashSet<(Value, OpenEdge)>, // dst, src +} + +impl Graph { + + pub fn new() -> Graph { + Graph{edges: HashSet::new()} + } + + pub fn with(&self, dst_val: Value, src_edge: OpenEdge) -> Self { + Graph{ + edges: self.edges.update((dst_val, src_edge)), + } + } } diff --git a/rust/src/gg/gg.bnf b/rust/src/gg/gg.bnf index c0e7760..3321945 100644 --- a/rust/src/gg/gg.bnf +++ b/rust/src/gg/gg.bnf @@ -1,19 +1,27 @@ + ::= | + ::= | | + ::= | "" + + ::= "-" + | + ::= | "" + ::= | | | - ::= "(" - ::= ")" | - ::= ")" - | "," - | "<" + ::= "(" + ::= ")" | + ::= ")" + | "," + | "<" - ::= "{" - ::= "}" | "<" - ::= "}" - | ";" - | "<" + ::= "{" + ::= "}" | "<" + ::= "}" + | ";" + | "<" - ::= - ::= | "<" - ::= - | ";" - | "<" + ::= + ::= | "<" + ::= + | ";" + | "<" diff --git a/rust/src/gg/lexer.rs b/rust/src/gg/lexer.rs index d6f7134..eb222d6 100644 --- a/rust/src/gg/lexer.rs +++ b/rust/src/gg/lexer.rs @@ -22,7 +22,7 @@ pub enum Error { IO(io::Error), } -impl From for Error{ +impl From for Error { fn from(e: io::Error) -> Self { Error::IO(e) } @@ -33,6 +33,7 @@ pub enum TokenKind { Name, Number, Punctuation, + End, } #[derive(Debug, PartialEq)] @@ -105,7 +106,7 @@ impl Lexer{ &mut self, kind: TokenKind, pred: impl Fn(char) -> bool, - ) -> Result, Error> { + ) -> Result<(Token, Location), Error> { let loc = self.next_loc; self.buf.truncate(0); @@ -115,8 +116,9 @@ impl Lexer{ let (c, ok) = self.peek_a_bool()?; if !ok || !pred(c) { - return Ok(Some( - (Token{kind: kind, value: self.buf.clone()}, loc) + return Ok(( + Token{kind: kind, value: self.buf.clone()}, + loc )) } @@ -129,13 +131,16 @@ impl Lexer{ c == '-' || ('0' <= c && c <= '9') } - pub fn next(&mut self) -> Result, Error> { + pub fn next(&mut self) -> Result<(Token, Location), Error> { loop { let (c, ok) = self.peek_a_bool()?; if !ok { - return Ok(None); + return Ok(( + Token{kind: TokenKind::End, value: String::new()}, + self.next_loc, + )); } else if c == '*' { self.discard_while(|c| c != '\n')?; @@ -155,15 +160,16 @@ impl Lexer{ let loc = self.next_loc; self.discard(); - return Ok(Some( - (Token{kind: TokenKind::Punctuation, value: c.to_string()}, loc) + return Ok(( + Token{kind: TokenKind::Punctuation, value: c.to_string()}, + loc, )) } else if c.is_ascii_whitespace() { self.discard_while(|c| c.is_ascii_whitespace())?; } else { - return Err(Error::Tokenizing("unexpected character", self.next_loc)); + return Err(Error::Tokenizing("invalid character", self.next_loc)); } } } @@ -192,26 +198,34 @@ mod tests { let tests = vec![ Test{ input: "", - exp: vec![], + exp: vec![ + tok(TokenKind::End, "", 0, 0), + ], }, Test{ input: "* foo", - exp: vec![], + exp: vec![ + tok(TokenKind::End, "", 0, 5), + ], }, Test{ input: "* foo\n", - exp: vec![], + exp: vec![ + tok(TokenKind::End, "", 1, 0), + ], }, Test{ input: "* foo\nbar", exp: vec![ tok(TokenKind::Name, "bar", 1, 0), + tok(TokenKind::End, "", 1, 3), ], }, Test{ input: "* foo\nbar ", exp: vec![ tok(TokenKind::Name, "bar", 1, 0), + tok(TokenKind::End, "", 1, 4), ], }, Test{ @@ -222,6 +236,7 @@ mod tests { tok(TokenKind::Name, "f-o", 1, 0), tok(TokenKind::Name, "f0O", 1, 4), tok(TokenKind::Name, "Foo", 1, 8), + tok(TokenKind::End, "", 1, 11), ], }, Test{ @@ -230,6 +245,7 @@ mod tests { tok(TokenKind::Number, "1", 0, 0), tok(TokenKind::Number, "100", 0, 2), tok(TokenKind::Number, "-100", 0, 6), + tok(TokenKind::End, "", 0, 10), ], }, Test{ @@ -242,6 +258,7 @@ mod tests { tok(TokenKind::Number, "-3", 0, 4), tok(TokenKind::Punctuation, "(", 0, 7), tok(TokenKind::Punctuation, ")", 0, 8), + tok(TokenKind::End, "", 0, 9), ], }, ]; @@ -253,9 +270,12 @@ mod tests { let mut res = Vec::new(); loop { - if let Some(token) = l.next().expect("no errors expected") { - res.push(token); - } else { + let (token, loc) = l.next().expect("no errors expected"); + let is_end = token.kind == TokenKind::End; + + res.push((token, loc)); + + if is_end { break; } } diff --git a/rust/src/graph.rs b/rust/src/graph.rs deleted file mode 100644 index eda2206..0000000 --- a/rust/src/graph.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::hash::Hash; -use im_rc::{HashMap,HashSet}; - -#[derive(Clone, Eq, Hash, PartialEq, Debug)] -pub enum OpenEdgeSource{ - Value(V), - Tuple(Vec>), -} - -#[derive(Clone, Eq, Hash, PartialEq, Debug)] -pub struct OpenEdge{ - value: E, - source: OpenEdgeSource, -} - -#[derive(Clone, Eq, Hash, PartialEq, Debug)] -pub struct Graph -where - E: Hash + Eq + Clone, - V: Hash + Eq + Clone, -{ - roots: HashMap>>, -} - -impl Graph -where - E: Hash + Eq + Clone, - V: Hash + Eq + Clone, -{ - - pub fn new() -> Graph { - Graph{roots: HashMap::new()} - } - - pub fn from_value(edge_value: E, source_value: V) -> OpenEdge { - OpenEdge{ - value: edge_value, - source: OpenEdgeSource::Value(source_value), - } - } - - pub fn from_tuple(edge_value: E, source_tuple: Vec>) -> OpenEdge { - OpenEdge{ - value: edge_value, - source: OpenEdgeSource::Tuple(source_tuple), - } - } - - pub fn with(&self, root_value: V, open_edge: OpenEdge) -> Self { - - let new_roots = self.roots.alter( - |set_option: Option>>| -> Option>> { - match set_option { - None => Some(HashSet::unit(open_edge)), - Some(set) => Some(set.update(open_edge)), - } - }, - root_value, - ); - - Graph{ - roots: new_roots, - } - } -} - diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 975fba2..2e78910 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,2 +1 @@ -pub mod graph; pub mod gg; diff --git a/rust/src/main.rs b/rust/src/main.rs index b048f2a..f79c691 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -1,22 +1,2 @@ -use ginger::graph::Graph; - fn main() { - - let g = Graph::new(). - with("foo", Graph::from_value(1, "bar")); - - let g1 = g. - with("foo", Graph::from_value(1, "bar")). - with("foo", Graph::from_value(2, "baz")); - - let g2 = g. - with("bar", Graph::from_tuple(100, vec![ - Graph::from_value(20, "a"), - Graph::from_value(40, "b"), - Graph::from_value(60, "c"), - ])); - - dbg!(g1 == g2); - dbg!(&g1); - dbg!(&g2); }