diff --git a/src/lib.rs b/src/lib.rs index dbfe7f3..f045c01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +pub mod parser; + const VERSION: &str = "0.0.1"; pub fn version() -> &'static str { diff --git a/src/parser/ast_node/ast_node.rs b/src/parser/ast_node/ast_node.rs new file mode 100644 index 0000000..644a198 --- /dev/null +++ b/src/parser/ast_node/ast_node.rs @@ -0,0 +1,135 @@ +// #[derive(Debug)] +use super::ast_node_concat::AstNodeConcat; +use super::ast_node_group::AstNodeGroup; +use super::ast_node_literal::AstNodeLiteral; +use super::ast_node_optional::AstNodeOptional; +use super::ast_node_plus::AstNodePlus; +use super::ast_node_star::AstNodeStar; +use super::ast_node_union::AstNodeUnion; + +pub(crate) enum AstNode { + Literal(AstNodeLiteral), + Concat(AstNodeConcat), + Union(AstNodeUnion), + Star(AstNodeStar), + Plus(AstNodePlus), + Optional(AstNodeOptional), + Group(AstNodeGroup), +} + +impl PartialEq for AstNode { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (AstNode::Literal(lhs), AstNode::Literal(rhs)) => lhs == rhs, + (AstNode::Concat(lhs), AstNode::Concat(rhs)) => lhs == rhs, + (AstNode::Union(lhs), AstNode::Union(rhs)) => lhs == rhs, + (AstNode::Star(lhs), AstNode::Star(rhs)) => lhs == rhs, + (AstNode::Plus(lhs), AstNode::Plus(rhs)) => lhs == rhs, + (AstNode::Optional(lhs), AstNode::Optional(rhs)) => lhs == rhs, + (AstNode::Group(lhs), AstNode::Group(rhs)) => lhs == rhs, + _ => false, + } + } +} + +impl std::fmt::Debug for AstNode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AstNode::Literal(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Concat(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Union(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Star(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Plus(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Optional(ast_node) => write!(f, "{:?}", ast_node), + AstNode::Group(ast_node) => write!(f, "{:?}", ast_node), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ast_node_literal_equality() { + let node1 = AstNode::Literal(AstNodeLiteral::new('a')); + let node2 = AstNode::Literal(AstNodeLiteral::new('a')); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_concat_equality() { + let node1 = AstNode::Concat(AstNodeConcat::new( + AstNode::Literal(AstNodeLiteral::new('a')), + AstNode::Literal(AstNodeLiteral::new('b')), + )); + let node2 = AstNode::Concat(AstNodeConcat::new( + AstNode::Literal(AstNodeLiteral::new('a')), + AstNode::Literal(AstNodeLiteral::new('b')), + )); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_union_equality() { + let node1 = AstNode::Union(AstNodeUnion::new( + AstNode::Literal(AstNodeLiteral::new('a')), + AstNode::Literal(AstNodeLiteral::new('b')), + )); + let node2 = AstNode::Union(AstNodeUnion::new( + AstNode::Literal(AstNodeLiteral::new('a')), + AstNode::Literal(AstNodeLiteral::new('b')), + )); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_star_equality() { + let node1 = AstNode::Star(AstNodeStar::new(AstNode::Literal(AstNodeLiteral::new('a')))); + let node2 = AstNode::Star(AstNodeStar::new(AstNode::Literal(AstNodeLiteral::new('a')))); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_plus_equality() { + let node1 = AstNode::Plus(AstNodePlus::new(AstNode::Literal(AstNodeLiteral::new('a')))); + let node2 = AstNode::Plus(AstNodePlus::new(AstNode::Literal(AstNodeLiteral::new('a')))); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_optional_equality() { + let node1 = AstNode::Optional(AstNodeOptional::new(AstNode::Literal(AstNodeLiteral::new( + 'a', + )))); + let node2 = AstNode::Optional(AstNodeOptional::new(AstNode::Literal(AstNodeLiteral::new( + 'a', + )))); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_group_equality() { + let node1 = AstNode::Group(AstNodeGroup::new(AstNode::Literal(AstNodeLiteral::new( + 'a', + )))); + let node2 = AstNode::Group(AstNodeGroup::new(AstNode::Literal(AstNodeLiteral::new( + 'a', + )))); + assert_eq!(node1, node2); + } + + #[test] + fn ast_node_basic_debug() { + let node = AstNode::Concat(AstNodeConcat::new( + AstNode::Star(AstNodeStar::new(AstNode::Union(AstNodeUnion::new( + AstNode::Literal(AstNodeLiteral::new('a')), + AstNode::Literal(AstNodeLiteral::new('b')), + )))), + AstNode::Optional(AstNodeOptional::new(AstNode::Group(AstNodeGroup::new( + AstNode::Plus(AstNodePlus::new(AstNode::Literal(AstNodeLiteral::new('c')))), + )))), + )); + assert_eq!(format!("{:?}", node), "Concat( Star( Union( Literal('a') Literal('b') ) ) Optional( Group( Plus ( Literal('c') ) ) ) )"); + } +} diff --git a/src/parser/ast_node/ast_node_concat.rs b/src/parser/ast_node/ast_node_concat.rs new file mode 100644 index 0000000..748bacf --- /dev/null +++ b/src/parser/ast_node/ast_node_concat.rs @@ -0,0 +1,27 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodeConcat { + m_op1: Box, + m_op2: Box, +} + +impl AstNodeConcat { + pub(crate) fn new(p0: AstNode, p1: AstNode) -> AstNodeConcat { + AstNodeConcat { + m_op1: Box::new(p0), + m_op2: Box::new(p1), + } + } +} + +impl PartialEq for AstNodeConcat { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 && self.m_op2 == other.m_op2 + } +} + +impl std::fmt::Debug for AstNodeConcat { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Concat( {:?} {:?} )", self.m_op1, self.m_op2) + } +} diff --git a/src/parser/ast_node/ast_node_group.rs b/src/parser/ast_node/ast_node_group.rs new file mode 100644 index 0000000..2d390be --- /dev/null +++ b/src/parser/ast_node/ast_node_group.rs @@ -0,0 +1,25 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodeGroup { + m_op1: Box, +} + +impl AstNodeGroup { + pub(crate) fn new(p0: AstNode) -> AstNodeGroup { + AstNodeGroup { + m_op1: Box::new(p0), + } + } +} + +impl PartialEq for AstNodeGroup { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 + } +} + +impl std::fmt::Debug for AstNodeGroup { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Group( {:?} )", self.m_op1) + } +} diff --git a/src/parser/ast_node/ast_node_literal.rs b/src/parser/ast_node/ast_node_literal.rs new file mode 100644 index 0000000..c23362c --- /dev/null +++ b/src/parser/ast_node/ast_node_literal.rs @@ -0,0 +1,23 @@ +use std::fmt; + +pub(crate) struct AstNodeLiteral { + m_value: char, +} + +impl AstNodeLiteral { + pub(crate) fn new(p0: char) -> AstNodeLiteral { + AstNodeLiteral { m_value: p0 } + } +} + +impl PartialEq for AstNodeLiteral { + fn eq(&self, other: &Self) -> bool { + self.m_value == other.m_value + } +} + +impl fmt::Debug for AstNodeLiteral { + fn fmt(&self, p: &mut fmt::Formatter) -> fmt::Result { + write!(p, "Literal({:?})", self.m_value) + } +} diff --git a/src/parser/ast_node/ast_node_optional.rs b/src/parser/ast_node/ast_node_optional.rs new file mode 100644 index 0000000..b151262 --- /dev/null +++ b/src/parser/ast_node/ast_node_optional.rs @@ -0,0 +1,25 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodeOptional { + m_op1: Box, +} + +impl AstNodeOptional { + pub(crate) fn new(p0: AstNode) -> AstNodeOptional { + AstNodeOptional { + m_op1: Box::new(p0), + } + } +} + +impl PartialEq for AstNodeOptional { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 + } +} + +impl std::fmt::Debug for AstNodeOptional { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Optional( {:?} )", self.m_op1) + } +} diff --git a/src/parser/ast_node/ast_node_plus.rs b/src/parser/ast_node/ast_node_plus.rs new file mode 100644 index 0000000..ea1e006 --- /dev/null +++ b/src/parser/ast_node/ast_node_plus.rs @@ -0,0 +1,25 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodePlus { + m_op1: Box, +} + +impl AstNodePlus { + pub(crate) fn new(p0: AstNode) -> AstNodePlus { + AstNodePlus { + m_op1: Box::new(p0), + } + } +} + +impl PartialEq for AstNodePlus { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 + } +} + +impl std::fmt::Debug for AstNodePlus { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Plus ( {:?} )", self.m_op1) + } +} diff --git a/src/parser/ast_node/ast_node_star.rs b/src/parser/ast_node/ast_node_star.rs new file mode 100644 index 0000000..8ca1c63 --- /dev/null +++ b/src/parser/ast_node/ast_node_star.rs @@ -0,0 +1,25 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodeStar { + m_op1: Box, +} + +impl AstNodeStar { + pub(crate) fn new(p0: AstNode) -> AstNodeStar { + AstNodeStar { + m_op1: Box::new(p0), + } + } +} + +impl PartialEq for AstNodeStar { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 + } +} + +impl std::fmt::Debug for AstNodeStar { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Star( {:?} )", self.m_op1) + } +} diff --git a/src/parser/ast_node/ast_node_union.rs b/src/parser/ast_node/ast_node_union.rs new file mode 100644 index 0000000..5cfe82a --- /dev/null +++ b/src/parser/ast_node/ast_node_union.rs @@ -0,0 +1,27 @@ +use crate::parser::ast_node::ast_node::AstNode; + +pub(crate) struct AstNodeUnion { + m_op1: Box, + m_op2: Box, +} + +impl AstNodeUnion { + pub(crate) fn new(p0: AstNode, p1: AstNode) -> AstNodeUnion { + AstNodeUnion { + m_op1: Box::new(p0), + m_op2: Box::new(p1), + } + } +} + +impl PartialEq for AstNodeUnion { + fn eq(&self, other: &Self) -> bool { + self.m_op1 == other.m_op1 && self.m_op2 == other.m_op2 + } +} + +impl std::fmt::Debug for AstNodeUnion { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Union( {:?} {:?} )", self.m_op1, self.m_op2) + } +} diff --git a/src/parser/ast_node/mod.rs b/src/parser/ast_node/mod.rs new file mode 100644 index 0000000..35a6ec4 --- /dev/null +++ b/src/parser/ast_node/mod.rs @@ -0,0 +1,8 @@ +pub mod ast_node; +mod ast_node_concat; +mod ast_node_group; +mod ast_node_literal; +mod ast_node_optional; +mod ast_node_plus; +mod ast_node_star; +mod ast_node_union; diff --git a/src/parser/mod.rs b/src/parser/mod.rs new file mode 100644 index 0000000..b8b7e88 --- /dev/null +++ b/src/parser/mod.rs @@ -0,0 +1,2 @@ +// Keep ASTNode private and they will be used by parser in the future +mod ast_node;