Skip to content

Commit

Permalink
Implement regex parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
inikulin committed May 18, 2020
1 parent ef4d4db commit 1fea9c9
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 37 deletions.
53 changes: 19 additions & 34 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions wirefilter-parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2018"
cidr = "0.1.0"
pest_consume = "1.0.4"
pest = "2.1.3"
regex = { version = "1.3.7", default-features = false, features = ["std", "perf"] }

[dev-dependencies]
indoc = "0.3.5"
32 changes: 31 additions & 1 deletion wirefilter-parser/src/ast.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use cidr::{Ipv4Cidr, Ipv6Cidr};
use regex::bytes::RegexBuilder;
use std::borrow::Cow;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::ops::RangeInclusive;
use std::ops::{Deref, RangeInclusive};
use std::str::FromStr;

#[derive(Debug, PartialEq)]
pub struct Var<'i>(pub Cow<'i, str>);

#[derive(Debug)]
pub struct Regex(regex::bytes::Regex);

#[derive(Debug, PartialEq)]
pub enum Rhs<'i> {
Int(i32),
Expand All @@ -17,6 +22,7 @@ pub enum Rhs<'i> {
Ipv6Range(RangeInclusive<Ipv6Addr>),
Ipv4Cidr(Ipv4Cidr),
Ipv6Cidr(Ipv6Cidr),
Regex(Regex),
}

#[derive(Debug, PartialEq)]
Expand All @@ -42,3 +48,27 @@ pub enum Expr<'i> {
rhs: Rhs<'i>,
},
}

impl PartialEq for Regex {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0.as_str() == other.0.as_str()
}
}

impl Deref for Regex {
type Target = regex::bytes::Regex;

#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl FromStr for Regex {
type Err = regex::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
RegexBuilder::new(s).unicode(false).build().map(Regex)
}
}
1 change: 0 additions & 1 deletion wirefilter-parser/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ re_ch_gr = _{ "[" ~ ( re_esc | re_ch_gr_unesc )* ~ "]" }
re_ch_gr_unesc = _{ ( !( "]" | "\\" ) ~ ANY )+ }



// Logical operators
//============================================================
logical_op = { op_or | op_and | op_xor }
Expand Down
22 changes: 21 additions & 1 deletion wirefilter-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,25 @@ impl Parser {
parse_type!(node, Ipv6Cidr)
}

#[inline]
fn ipv4_range(node: Node) -> ParseResult<RangeInclusive<Ipv4Addr>> {
parse_range!(node, ipv4_lit)
}

#[inline]
fn ipv6_range(node: Node) -> ParseResult<RangeInclusive<Ipv6Addr>> {
parse_range!(node, ipv6_lit)
}

fn re_lit(node: Node) -> ParseResult<ast::Regex> {
node.children()
.single()
.unwrap()
.as_str()
.parse()
.into_parse_result(&node)
}

fn rhs(node: Node) -> ParseResult<ast::Rhs> {
Ok(match_nodes! {
node.children();
Expand All @@ -164,7 +175,8 @@ impl Parser {
[ipv4_cidr(c)] => ast::Rhs::Ipv4Cidr(c),
[ipv6_cidr(c)] => ast::Rhs::Ipv6Cidr(c),
[ipv4_range(r)] => ast::Rhs::Ipv4Range(r),
[ipv6_range(r)] => ast::Rhs::Ipv6Range(r)
[ipv6_range(r)] => ast::Rhs::Ipv6Range(r),
[re_lit(r)] => ast::Rhs::Regex(r)
})
}

Expand Down Expand Up @@ -604,4 +616,12 @@ mod tests {
= start of the range is greater than the end"
}
}

#[test]
fn parse_re_lit() {
ok! {
re_lit r#"/[-]?[0-9]+[,.]?[0-9]*([\/][0-9]+[,.]?[0-9]*)*/"# =>
r#"[-]?[0-9]+[,.]?[0-9]*([\/][0-9]+[,.]?[0-9]*)*"#.parse().unwrap()
}
}
}

0 comments on commit 1fea9c9

Please sign in to comment.