|
|
|
@ -5,6 +5,7 @@ pub enum Error {}
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
|
pub enum Token {
|
|
|
|
|
Ident(String),
|
|
|
|
|
Pipe,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
@ -30,7 +31,11 @@ impl<'text> Lexer<'text> {
|
|
|
|
|
while self.peek().is_some() {
|
|
|
|
|
self.skip_whitespace();
|
|
|
|
|
match self.peek() {
|
|
|
|
|
None => { return Ok(tokens) },
|
|
|
|
|
None => return Ok(tokens),
|
|
|
|
|
Some('|') => {
|
|
|
|
|
tokens.push(Token::Pipe);
|
|
|
|
|
self.skip();
|
|
|
|
|
}
|
|
|
|
|
Some(_) => {
|
|
|
|
|
tokens.push(self.ident());
|
|
|
|
|
}
|
|
|
|
@ -76,7 +81,7 @@ impl<'text> Lexer<'text> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn ident(&mut self) -> Token {
|
|
|
|
|
let mut kept: Vec<char> = vec!();
|
|
|
|
|
let mut kept: Vec<char> = vec![];
|
|
|
|
|
loop {
|
|
|
|
|
match self.peek() {
|
|
|
|
|
None => break,
|
|
|
|
@ -93,39 +98,97 @@ impl<'text> Lexer<'text> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pub fn parse(line: String) -> Result<Tree, Error> {
|
|
|
|
|
// Ok(Tree::new())
|
|
|
|
|
// }
|
|
|
|
|
struct Parser {
|
|
|
|
|
|
|
|
|
|
// pub struct Tree {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// impl Tree {
|
|
|
|
|
// pub fn new() -> Self { Self { } }
|
|
|
|
|
// }
|
|
|
|
|
struct Tree {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn parse<S: AsRef<str>>(text: S) -> Result<Tree, Error> {
|
|
|
|
|
Ok(Tree{})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
use Token::Pipe;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn lex_empty() -> Result<(), Error> {
|
|
|
|
|
let tokens = lex("")?;
|
|
|
|
|
assert_eq!(tokens.len(), 0);
|
|
|
|
|
Ok(())
|
|
|
|
|
fn ident<S: Into<String>>(s: S) -> Token {
|
|
|
|
|
Token::Ident(s.into())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! lex {
|
|
|
|
|
(
|
|
|
|
|
$($name:ident: $line:literal $($token:expr)* ;)+
|
|
|
|
|
) => {
|
|
|
|
|
$(
|
|
|
|
|
#[test]
|
|
|
|
|
fn lex_ident() -> Result<(), Error> {
|
|
|
|
|
let tokens = lex("one")?;
|
|
|
|
|
assert_eq!(tokens.len(), 1);
|
|
|
|
|
assert_eq!(tokens[0], Token::Ident(String::from("one")));
|
|
|
|
|
|
|
|
|
|
let tokens = lex("one two")?;
|
|
|
|
|
assert_eq!(tokens.len(), 2);
|
|
|
|
|
assert_eq!(tokens[0], Token::Ident(String::from("one")));
|
|
|
|
|
assert_eq!(tokens[1], Token::Ident(String::from("two")));
|
|
|
|
|
fn $name() -> Result<(), Error> {
|
|
|
|
|
let mut tokens = lex($line)?;
|
|
|
|
|
|
|
|
|
|
$(
|
|
|
|
|
assert!(tokens.len() > 0);
|
|
|
|
|
let front = tokens.remove(0);
|
|
|
|
|
assert_eq!($token, front);
|
|
|
|
|
)*
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
)*
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lex! {
|
|
|
|
|
single_token:
|
|
|
|
|
"one"
|
|
|
|
|
ident("one");
|
|
|
|
|
|
|
|
|
|
two_tokens:
|
|
|
|
|
"one two"
|
|
|
|
|
ident("one") ident("two");
|
|
|
|
|
|
|
|
|
|
leading_whitespace:
|
|
|
|
|
" one"
|
|
|
|
|
ident("one");
|
|
|
|
|
|
|
|
|
|
trailing_whitespace:
|
|
|
|
|
"one "
|
|
|
|
|
ident("one");
|
|
|
|
|
|
|
|
|
|
surrounding_whitespace:
|
|
|
|
|
" one "
|
|
|
|
|
ident("one");
|
|
|
|
|
|
|
|
|
|
internal_hyphen:
|
|
|
|
|
"one-two"
|
|
|
|
|
ident("one-two");
|
|
|
|
|
|
|
|
|
|
pipe:
|
|
|
|
|
"|"
|
|
|
|
|
Pipe;
|
|
|
|
|
|
|
|
|
|
pipeline:
|
|
|
|
|
"one | two"
|
|
|
|
|
ident("one") Pipe ident("two");
|
|
|
|
|
|
|
|
|
|
pipeline_2:
|
|
|
|
|
"one |two"
|
|
|
|
|
ident("one") Pipe ident("two");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|