mirror of https://github.com/tildeio/helix
Implement or, fix scanner bugz
This commit is contained in:
parent
393abea3cb
commit
c1c614e6ee
|
@ -4,4 +4,12 @@ use scanner;
|
|||
pub enum Expression {
|
||||
Token(scanner::Token),
|
||||
Group(Vec<Expression>),
|
||||
Or(Vec<Expression>),
|
||||
}
|
||||
|
||||
pub fn concat<T: Clone>(lhs: T, rhs: &[T]) -> Vec<T> {
|
||||
let mut v = Vec::with_capacity(1 + rhs.len());
|
||||
v.push(lhs);
|
||||
v.extend_from_slice(rhs);
|
||||
v
|
||||
}
|
||||
|
|
|
@ -4,30 +4,31 @@ use nodes::*;
|
|||
grammar;
|
||||
|
||||
pub Expressions: Vec<Expression> = {
|
||||
<e: Expression> <rest: Expressions> => {
|
||||
let mut v = Vec::with_capacity(1 + rest.len());
|
||||
v.push(e);
|
||||
v.extend_from_slice(&rest);
|
||||
v
|
||||
},
|
||||
<e: Expression> <rest: Expressions> => { concat(e, &rest) },
|
||||
<Expression> => { vec![<>] },
|
||||
<Or> => { vec![Expression::Or(<>)] }
|
||||
}
|
||||
|
||||
pub Expression: Expression = {
|
||||
<Terminal> => { Expression::Token(<>) },
|
||||
<Group> => { Expression::Group(<>) },
|
||||
<Star> => { Expression::Token(<>) }
|
||||
<STAR> => { Expression::Token(<>) }
|
||||
}
|
||||
|
||||
pub Group: Vec<Expression> = {
|
||||
LParen <Expressions> RParen
|
||||
LPAREN <Expressions> RPAREN
|
||||
}
|
||||
|
||||
pub Or: Vec<Expression> = {
|
||||
<lhs: Expression> OR <rhs: Expression> => { vec![lhs, rhs] },
|
||||
<lhs: Expression> OR <rhs: Or> => { concat(lhs, &rhs) },
|
||||
}
|
||||
|
||||
pub Terminal: Token = {
|
||||
<Symbol>,
|
||||
<Literal>,
|
||||
<Slash>,
|
||||
<Dot>
|
||||
<SYMBOL>,
|
||||
<LITERAL>,
|
||||
<SLASH>,
|
||||
<DOT>
|
||||
}
|
||||
|
||||
extern {
|
||||
|
@ -35,13 +36,13 @@ extern {
|
|||
type Error = NotPossible;
|
||||
|
||||
enum Token {
|
||||
Slash => Token::Slash,
|
||||
LParen => Token::LParen,
|
||||
RParen => Token::RParen,
|
||||
Dot => Token::Dot,
|
||||
Or => Token::Or,
|
||||
Star => Token::Star(_),
|
||||
Symbol => Token::Symbol(_),
|
||||
Literal => Token::Literal(_),
|
||||
SLASH => Token::Slash,
|
||||
LPAREN => Token::LParen,
|
||||
RPAREN => Token::RParen,
|
||||
DOT => Token::Dot,
|
||||
OR => Token::Or,
|
||||
STAR => Token::Star(_),
|
||||
SYMBOL => Token::Symbol(_),
|
||||
LITERAL => Token::Literal(_),
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
use owned_chars::{OwnedCharIndices, OwnedCharsExt};
|
||||
use std;
|
||||
use owned_chars::{OwnedCharsExt, OwnedCharIndices};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Token {
|
||||
|
@ -44,7 +44,7 @@ impl Scanner {
|
|||
|
||||
fn consume_symbol_or_star(&mut self) -> Option<(usize, String, usize)> {
|
||||
if self.peek_char().is_none() {
|
||||
return None
|
||||
return None;
|
||||
} else {
|
||||
let mut ident = String::new();
|
||||
let start = self.peek_char().unwrap().0;
|
||||
|
@ -59,12 +59,14 @@ impl Scanner {
|
|||
let is_boundary = match self.peek_char() {
|
||||
Some((_, c)) => match c {
|
||||
'_' => false,
|
||||
c => !c.is_ascii_alphanumeric(),
|
||||
c => !c.is_ascii_alphanumeric(),
|
||||
},
|
||||
None => true
|
||||
None => true,
|
||||
};
|
||||
|
||||
if is_boundary { break; }
|
||||
if is_boundary {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Some((start, ident, end))
|
||||
|
@ -73,7 +75,7 @@ impl Scanner {
|
|||
|
||||
fn consume_literal(&mut self) -> Option<(usize, String, usize)> {
|
||||
if self.peek_char().is_none() {
|
||||
return None
|
||||
return None;
|
||||
} else {
|
||||
let mut ident = String::new();
|
||||
let start = self.peek_char().unwrap().0;
|
||||
|
@ -92,13 +94,15 @@ impl Scanner {
|
|||
|
||||
let is_boundary = match self.peek_char() {
|
||||
Some((_, c)) => match c {
|
||||
'/' => true,
|
||||
_ => false,
|
||||
'/' | '(' | ')' | '.' | '|' => true,
|
||||
_ => false,
|
||||
},
|
||||
None => true
|
||||
None => true,
|
||||
};
|
||||
|
||||
if is_boundary { break; }
|
||||
if is_boundary {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Some((start, ident, end))
|
||||
|
@ -119,35 +123,35 @@ impl Iterator for Scanner {
|
|||
'/' => {
|
||||
self.consume_char();
|
||||
Ok((loc, Slash, loc))
|
||||
},
|
||||
}
|
||||
'(' => {
|
||||
self.consume_char();
|
||||
Ok((loc, LParen, loc))
|
||||
},
|
||||
}
|
||||
')' => {
|
||||
self.consume_char();
|
||||
Ok((loc, RParen, loc))
|
||||
},
|
||||
}
|
||||
'.' => {
|
||||
self.consume_char();
|
||||
Ok((loc, Dot, loc))
|
||||
},
|
||||
}
|
||||
'|' => {
|
||||
self.consume_char();
|
||||
Ok((loc, Or, loc))
|
||||
},
|
||||
}
|
||||
'*' => {
|
||||
let (start, ident, end) = self.consume_symbol_or_star().unwrap();
|
||||
Ok((start, Star(ident), end))
|
||||
},
|
||||
}
|
||||
':' => {
|
||||
let (start, ident, end) = self.consume_symbol_or_star().unwrap();
|
||||
Ok((start, Symbol(ident), end))
|
||||
},
|
||||
_ => {
|
||||
}
|
||||
_ => {
|
||||
let (start, ident, end) = self.consume_literal().unwrap();
|
||||
Ok((start, Literal(ident), end))
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
extern crate lalrpop_util;
|
||||
|
||||
use parser::*;
|
||||
use scanner::{self, Scanner, Token::*};
|
||||
use nodes::Expression::{self, *};
|
||||
use parser::ExpressionsParser;
|
||||
use scanner::Token::{Dot, Literal, Slash, Star, Symbol};
|
||||
use scanner::{self, Scanner};
|
||||
|
||||
type ParseError = lalrpop_util::ParseError<usize, scanner::Token, scanner::NotPossible>;
|
||||
type ParseResult = Result<Vec<Expression>, ParseError>;
|
||||
|
@ -15,259 +16,385 @@ fn parse(s: &'static str) -> ParseResult {
|
|||
|
||||
#[test]
|
||||
fn test_slash() {
|
||||
assert_eq!(parse("/").unwrap(), vec![
|
||||
Token(Slash)
|
||||
]);
|
||||
assert_eq!(parse("/").unwrap(), vec![Token(Slash)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment() {
|
||||
assert_eq!(parse("foo").unwrap(), vec![
|
||||
Token(Literal("foo".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("foo").unwrap(),
|
||||
vec![Token(Literal("foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(parse("/foo").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo").unwrap(),
|
||||
vec![Token(Slash), Token(Literal("foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(parse("/foo/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segments() {
|
||||
assert_eq!(parse("/foo/bar/baz").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("baz".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo/bar/baz").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("baz".to_string())),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(parse("/foo/bar/baz/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("baz".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symbol() {
|
||||
assert_eq!(parse(":foo").unwrap(), vec![
|
||||
Token(Symbol(":foo".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/:foo").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/:foo/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo/bar/baz/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("baz".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_symbol() {
|
||||
assert_eq!(parse("/foo/:id").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Symbol(":id".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo/:id").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Symbol(":id".to_string())),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symbol() {
|
||||
assert_eq!(
|
||||
parse(":foo").unwrap(),
|
||||
vec![Token(Symbol(":foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/:foo").unwrap(),
|
||||
vec![Token(Slash), Token(Symbol(":foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/:foo/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_group() {
|
||||
assert_eq!(parse("(/:foo)").unwrap(), vec![
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string()))
|
||||
])
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("(/:foo)").unwrap(),
|
||||
vec![Group(vec![Token(Slash), Token(Symbol(":foo".to_string()))])]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups() {
|
||||
assert_eq!(parse("(/:foo)(/:bar)").unwrap(), vec![
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string()))
|
||||
]),
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
])
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("(/:foo)(/:bar)").unwrap(),
|
||||
vec![
|
||||
Group(vec![Token(Slash), Token(Symbol(":foo".to_string()))]),
|
||||
Group(vec![Token(Slash), Token(Symbol(":bar".to_string()))]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_groups() {
|
||||
assert_eq!(parse("(/:foo(/:bar))").unwrap(), vec![
|
||||
Group(vec![
|
||||
assert_eq!(
|
||||
parse("(/:foo(/:bar))").unwrap(),
|
||||
vec![Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":foo".to_string())),
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
])
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_star() {
|
||||
assert_eq!(parse("*foo").unwrap(), vec![
|
||||
Token(Star("*foo".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/*foo").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/*foo/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/foo/*bar").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Star("*bar".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/foo/*bar/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Star("*bar".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/*foo/bar").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string()))
|
||||
]);
|
||||
|
||||
assert_eq!(parse("/*foo/bar/").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash)
|
||||
]);
|
||||
Group(vec![Token(Slash), Token(Symbol(":bar".to_string()))]),
|
||||
])]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dot_symbol() {
|
||||
assert_eq!(parse(".:format").unwrap(), vec![
|
||||
Token(Dot),
|
||||
Token(Symbol(":format".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse(".:format").unwrap(),
|
||||
vec![Token(Dot), Token(Symbol(":format".to_string()))]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dot_literal() {
|
||||
assert_eq!(parse(".xml").unwrap(), vec![
|
||||
Token(Dot),
|
||||
Token(Literal("xml".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse(".xml").unwrap(),
|
||||
vec![Token(Dot), Token(Literal("xml".to_string()))]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_dot() {
|
||||
assert_eq!(parse("/foo.:bar").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Dot),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo.:bar").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Dot),
|
||||
Token(Symbol(":bar".to_string())),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_group_dot() {
|
||||
assert_eq!(parse("/foo(.:bar)").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
Token(Dot),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
])
|
||||
]);
|
||||
assert_eq!(
|
||||
parse("/foo(.:bar)").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![Token(Dot), Token(Symbol(":bar".to_string()))]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_group() {
|
||||
assert_eq!(parse("/foo(/:action)").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
assert_eq!(
|
||||
parse("/foo(/:action)").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":action".to_string()))
|
||||
])
|
||||
]);
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![Token(Slash), Token(Symbol(":action".to_string()))]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_groups() {
|
||||
assert_eq!(parse("/foo(/:action)(/:bar)").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
assert_eq!(
|
||||
parse("/foo(/:action)(/:bar)").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":action".to_string()))
|
||||
]),
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
])
|
||||
]);
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![Token(Slash), Token(Symbol(":action".to_string()))]),
|
||||
Group(vec![Token(Slash), Token(Symbol(":bar".to_string()))]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_segment_nested_groups() {
|
||||
assert_eq!(parse("/foo(/:action(/:bar))").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
assert_eq!(
|
||||
parse("/foo(/:action(/:bar))").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":action".to_string())),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
])
|
||||
])
|
||||
]);
|
||||
Token(Symbol(":action".to_string())),
|
||||
Group(vec![Token(Slash), Token(Symbol(":bar".to_string()))]),
|
||||
]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_group_followed_by_path() {
|
||||
assert_eq!(parse("/foo(/:action)/:bar").unwrap(), vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![
|
||||
assert_eq!(
|
||||
parse("/foo(/:action)/:bar").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Symbol(":action".to_string()))
|
||||
]),
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string()))
|
||||
]);
|
||||
Token(Literal("foo".to_string())),
|
||||
Group(vec![Token(Slash), Token(Symbol(":action".to_string()))]),
|
||||
Token(Slash),
|
||||
Token(Symbol(":bar".to_string())),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_star() {
|
||||
assert_eq!(
|
||||
parse("*foo").unwrap(),
|
||||
vec![Token(Star("*foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/*foo").unwrap(),
|
||||
vec![Token(Slash), Token(Star("*foo".to_string()))]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/*foo/").unwrap(),
|
||||
vec![Token(Slash), Token(Star("*foo".to_string())), Token(Slash)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/foo/*bar").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Star("*bar".to_string())),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/foo/*bar/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Star("*bar".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/*foo/bar").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/*foo/bar/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Star("*foo".to_string())),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/foo/(*bar)").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Group(vec![Token(Star("*bar".to_string()))]),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/foo/(*bar)/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Token(Literal("foo".to_string())),
|
||||
Token(Slash),
|
||||
Group(vec![Token(Star("*bar".to_string()))]),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/(*foo)/bar").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Group(vec![Token(Star("*foo".to_string()))]),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("/(*foo)/bar/").unwrap(),
|
||||
vec![
|
||||
Token(Slash),
|
||||
Group(vec![Token(Star("*foo".to_string()))]),
|
||||
Token(Slash),
|
||||
Token(Literal("bar".to_string())),
|
||||
Token(Slash),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
assert_eq!(
|
||||
parse("a|b").unwrap(),
|
||||
vec![Or(vec![
|
||||
Token(Literal("a".to_string())),
|
||||
Token(Literal("b".to_string())),
|
||||
])]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("a|b|c").unwrap(),
|
||||
vec![Or(vec![
|
||||
Token(Literal("a".to_string())),
|
||||
Token(Literal("b".to_string())),
|
||||
Token(Literal("c".to_string())),
|
||||
])]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("(a|b)|c").unwrap(),
|
||||
vec![Or(vec![
|
||||
Group(vec![Or(vec![
|
||||
Token(Literal("a".to_string())),
|
||||
Token(Literal("b".to_string())),
|
||||
])]),
|
||||
Token(Literal("c".to_string())),
|
||||
])]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("a|(b|c)").unwrap(),
|
||||
vec![Or(vec![
|
||||
Token(Literal("a".to_string())),
|
||||
Group(vec![Or(vec![
|
||||
Token(Literal("b".to_string())),
|
||||
Token(Literal("c".to_string())),
|
||||
])]),
|
||||
])]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("*a|(b|c)").unwrap(),
|
||||
vec![Or(vec![
|
||||
Token(Star("*a".to_string())),
|
||||
Group(vec![Or(vec![
|
||||
Token(Literal("b".to_string())),
|
||||
Token(Literal("c".to_string())),
|
||||
])]),
|
||||
])]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
parse("*a|(:b|c)").unwrap(),
|
||||
vec![Or(vec![
|
||||
Token(Star("*a".to_string())),
|
||||
Group(vec![Or(vec![
|
||||
Token(Symbol(":b".to_string())),
|
||||
Token(Literal("c".to_string())),
|
||||
])]),
|
||||
])]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -292,7 +419,6 @@ fn parse_invalid_paths() {
|
|||
// assert!(parse(")").is_err());
|
||||
// }
|
||||
|
||||
|
||||
// #[test]
|
||||
// fn parse_path() {
|
||||
// let scanner = Scanner::new("/foo/bar".to_string());
|
||||
|
|
Loading…
Reference in New Issue