fixed term handling

This commit is contained in:
nora 2021-10-24 00:43:10 +02:00
parent 318d56eb65
commit 87de737bf3

View file

@ -23,11 +23,10 @@ use std::str::Chars;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Regex { pub enum Regex {
Choice(Box<Regex>, Box<Regex>), Choice(Box<Regex>, Box<Regex>),
Sequence(Box<Regex>, Box<Regex>), Sequence(Vec<Regex>),
Repetition(Box<Regex>), Repetition(Box<Regex>),
Primitive(char), Primitive(char),
Char(char), Char(char),
Blank,
} }
#[derive(Debug)] #[derive(Debug)]
@ -75,18 +74,19 @@ impl<'a> Parser<'a> {
} }
} }
/// a term is a sequence of factors
fn term(&mut self) -> RegexResult { fn term(&mut self) -> RegexResult {
let mut factor = Regex::Blank; let mut sequence = Vec::new();
loop { loop {
if let None | Some(')') | Some('|') = self.peek() { if let None | Some(')') | Some('|') = self.peek() {
break; break;
} }
let next_factor = self.factor()?; let next_factor = self.factor()?;
factor = Regex::Sequence(Box::new(factor), Box::new(next_factor)); sequence.push(next_factor);
} }
Ok(factor) Ok(Regex::Sequence(sequence))
} }
fn factor(&mut self) -> RegexResult { fn factor(&mut self) -> RegexResult {
@ -124,7 +124,11 @@ impl<'a> Parser<'a> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::parse::{Parser, Regex}; use crate::parse::{Parser, Regex, Regex::*};
fn box_seq(elements: Vec<Regex>) -> Box<Regex> {
Box::new(Sequence(elements))
}
#[test] #[test]
fn simple_choice() { fn simple_choice() {
@ -132,7 +136,7 @@ mod test {
let parsed = Parser::parse(regex).unwrap(); let parsed = Parser::parse(regex).unwrap();
assert_eq!( assert_eq!(
parsed, parsed,
Regex::Choice(Box::new(Regex::Char('a')), Box::new(Regex::Char('b'))) Choice(box_seq(vec![Char('a')]), box_seq(vec![Char('b')]))
) )
} }
@ -140,6 +144,6 @@ mod test {
fn repetition() { fn repetition() {
let regex = "a*"; let regex = "a*";
let parsed = Parser::parse(regex).unwrap(); let parsed = Parser::parse(regex).unwrap();
assert_eq!(parsed, Regex::Repetition(Box::new(Regex::Char('a')))) assert_eq!(parsed, Sequence(vec![Repetition(Box::new(Char('a')))]))
} }
} }